aboutsummaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAdrien Tétar2015-05-02 22:04:08 +0200
committerAdrien Tétar2015-05-02 22:04:08 +0200
commitc55eac755c6c7d91010f9b3ba040bc356f350ca7 (patch)
treecc267b14ad50595ed3df7b68c0d864e9d1dd5094 /Lib
parent7f54aa17a9c49a8688ee64e2aba303769ebb6c53 (diff)
downloadtrufont-c55eac755c6c7d91010f9b3ba040bc356f350ca7.tar.bz2
More, glyph canvas
Diffstat (limited to 'Lib')
-rw-r--r--Lib/defconQt/fontView.py176
-rw-r--r--Lib/defconQt/glyphView.py6
-rw-r--r--Lib/defconQt/spacecenter.py56
-rw-r--r--Lib/defconQt/svgViewer.py87
-rw-r--r--Lib/defconQt/syntaxhighlighter.py74
5 files changed, 290 insertions, 109 deletions
diff --git a/Lib/defconQt/fontView.py b/Lib/defconQt/fontView.py
index 114a5ca..6fc0207 100644
--- a/Lib/defconQt/fontView.py
+++ b/Lib/defconQt/fontView.py
@@ -4,12 +4,9 @@ import representationFactories
import unicodedata
from defcon import Font
-from PyQt5.QtCore import pyqtSignal, QSize, Qt
-from PyQt5.QtGui import (QClipboard, QFont, QFontDatabase, QFontMetrics,
- QIcon, QPainter)
-from PyQt5.QtWidgets import (QApplication, QCheckBox, QComboBox, QDialogButtonBox, QFileDialog, QFontComboBox,
- QFrame, QHBoxLayout, QLabel, QLineEdit, QMainWindow, QMessageBox, QMenu, QPushButton,
- QScrollArea, QTabWidget, QToolTip, QVBoxLayout, QWidget)
+from PyQt5.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtWidgets import *
glyphSortDescriptors = [
dict(type="alphabetical", allowPseudoUnicode=True),
@@ -21,18 +18,19 @@ glyphSortDescriptors = [
]
class CharacterWidget(QWidget):
- #characterSelected = pyqtSignal(str)
+ characterSelected = pyqtSignal(int, str)
- def __init__(self, font, parent=None):
+ def __init__(self, font, squareSize=48, parent=None):
super(CharacterWidget, self).__init__(parent)
self.font = font
self.glyphs = [font[k] for k in font.unicodeData.sortGlyphNames(font.keys(), glyphSortDescriptors)]
- self.squareSize = 48
+ self.squareSize = squareSize
self.columns = 11
self.lastKey = -1
- self.setMouseTracking(True)
- self.col = Qt.red
+ self.moveKey = -1
+ #self.setMouseTracking(True)
+ self.col = QColor.fromRgbF(.2, .3, .7, .15)
def updateFont(self, font):
self.font = font
@@ -47,55 +45,73 @@ class CharacterWidget(QWidget):
self.update()
def sizeHint(self):
- # TODO: adding 2 to glyphlen is cheating, need to find how to properly compensate y_offset
- # But why does it even have to be? Does Qt take the origin the painting as the basis for size calculation? Likely...
return QSize(self.columns * self.squareSize,
- (len(self.glyphs)+2) / self.columns * self.squareSize)
-
- def mouseMoveEvent(self, event):
- if event.modifiers() & Qt.ControlModifier:
- widgetPosition = self.mapFromGlobal(event.globalPos())
- key = (widgetPosition.y() // self.squareSize) * self.columns + widgetPosition.x() // self.squareSize
- uni = self.glyphs[key].unicode
- char = chr(self.glyphs[key].unicode) if uni is not None else "?"
-
- # http://stackoverflow.com/questions/6598554/is-there-any-way-to-insert-qpixmap-object-in-html
- text = '<p align="center" style="font-size: 36pt; font-family: %s">%s</p>' % (QFont().family(), char)
- if uni is not None:
- text += '<p>U+%04x<p>' % self.glyphs[key].unicode
- QToolTip.showText(event.globalPos(), text, self)
+ math.ceil(len(self.glyphs) / self.columns) * self.squareSize)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.lastKey = (event.y() // self.squareSize) * self.columns + event.x() // self.squareSize
- #key_ch = self._chr(self.lastKey)
- self.col = Qt.red
-
- """
- if unicodedata.category(key_ch) != 'Cn':
- self.characterSelected.emit(key_ch)
- """
+ self.moveKey = -1
+ if self.lastKey > len(self.glyphs)-1: return
+
+ self.col = QColor.fromRgbF(.2, .3, .7, .15)
+ uniValue = self.glyphs[self.lastKey].unicode
+ showName = uniValue is None or unicodedata.category(chr(uniValue)) == 'Zs'
+ self.characterSelected.emit(1, chr(uniValue) if not showName else self.glyphs[self.lastKey].name)
+ event.accept()
self.update()
else:
super(CharacterWidget, self).mousePressEvent(event)
-
+
+ def mouseMoveEvent(self, event):
+ if event.buttons() & Qt.LeftButton:
+ moveKey = (event.y() // self.squareSize) * self.columns + event.x() // self.squareSize
+ event.accept()
+ if (moveKey == self.lastKey and self.moveKey != -1):
+ self.moveKey = -1
+ # code duplication :(
+ uniValue = self.glyphs[self.lastKey].unicode
+ showName = uniValue is None or unicodedata.category(chr(uniValue)) == 'Zs'
+ self.characterSelected.emit(1, chr(uniValue) if not showName else self.glyphs[self.lastKey].name)
+ elif moveKey > len(self.glyphs)-1 \
+ or not (moveKey != self.lastKey and moveKey != self.moveKey): return
+ else:
+ self.moveKey = moveKey
+ self.characterSelected.emit(abs(self.moveKey - self.lastKey)+1, "")
+ self.update()
+ # elif event.modifiers() & Qt.ControlModifier:
+ # widgetPosition = self.mapFromGlobal(event.globalPos())
+ # key = (widgetPosition.y() // self.squareSize) * self.columns + widgetPosition.x() // self.squareSize
+ # uni = self.glyphs[key].unicode
+ # char = chr(self.glyphs[key].unicode) if uni is not None else "?"
+
+ # # http://stackoverflow.com/questions/6598554/is-there-any-way-to-insert-qpixmap-object-in-html
+ # text = '<p align="center" style="font-size: 36pt; font-family: %s">%s</p>' % (QFont().family(), char)
+ # if uni is not None:
+ # text += '<p>U+%04x<p>' % self.glyphs[key].unicode
+ # text += '<p>%s<p>' % unicodedata.name(chr(self.glyphs[key].unicode))
+ # QToolTip.showText(event.globalPos(), text, self)
+ else:
+ super(CharacterWidget, self).mouseMoveEvent(event)
+
+ def mouseReleaseEvent(self, event):
+ if event.button() == Qt.LeftButton:
+ event.accept()
+ else:
+ super(CharacterWidget, self).mouseReleaseEvent(event)
+
def mouseDoubleClickEvent(self, event):
if event.button() == Qt.LeftButton:
self.lastKey = (event.y() // self.squareSize) * self.columns + event.x() // self.squareSize
- #key_ch = self._chr(self.lastKey)
self.col = Qt.green
- """
- if unicodedata.category(key_ch) != 'Cn':
- self.characterSelected.emit(key_ch)
- """
self.update()
else:
super(CharacterWidget, self).mousePressEvent(event)
'''
def resizeEvent(self, event):
- self.columns = event.rect().right() // self.squareSize
+ self.columns = event.size().width() // self.squareSize
'''
def paintEvent(self, event):
@@ -109,23 +125,51 @@ class CharacterWidget(QWidget):
beginColumn = redrawRect.left() // self.squareSize
endColumn = redrawRect.right() // self.squareSize
+ # selection code
+ firstKey = min(self.lastKey, self.moveKey)
+ lastKey = max(self.lastKey, self.moveKey)
+ minKeyInViewport = beginRow * self.columns + beginColumn
+ select = False
+ if firstKey != -1 and firstKey < minKeyInViewport and lastKey > minKeyInViewport:
+ select = True
+
+ # if firstKey == -1:
+ # column = lastKey % self.columns
+ # row = lastKey // self.columns
+ # painter.fillRect(column * self.squareSize + 1,
+ # row * self.squareSize + 1, self.squareSize - 2,
+ # self.squareSize - 2, self.col)
+ # else:
+ # row_d = firstKey // self.columns
+ # row_a = lastKey // self.columns
+ # for row in range(row_d, row_a+1):
+ # col_d = firstKey % self.columns if row == row_d else 0
+ # col_a = lastKey % self.columns if row == row_a else self.columns
+ # for column in range(col_d, col_a+1):
+ # painter.fillRect(column * self.squareSize + 1,
+ # row * self.squareSize + 1, self.squareSize - 2,
+ # self.squareSize - 2, self.col)
+
painter.setPen(Qt.gray)
for row in range(beginRow, endRow + 1):
for column in range(beginColumn, endColumn + 1):
+ key = row * self.columns + column
+ if key > len(self.glyphs)-1: break
+
painter.drawRect(column * self.squareSize,
row * self.squareSize, self.squareSize,
self.squareSize)
- for row in range(beginRow, endRow + 1):
- for column in range(beginColumn, endColumn + 1):
- key = row * self.columns + column
-
- if key == self.lastKey:
+ # selection code
+ if key == firstKey:
+ select = not select
+ if select or (key == self.lastKey and self.moveKey == -1):
painter.fillRect(column * self.squareSize + 1,
row * self.squareSize + 1, self.squareSize - 2,
self.squareSize - 2, self.col)
+ if key == lastKey and self.moveKey != -1:
+ select = not select
- if key > len(self.glyphs)-1: break
glyph = self.glyphs[key].getRepresentation("defconQt.QPainterPath")
if self.font.info.unitsPerEm is None: break
if not self.font.info.unitsPerEm > 0: self.font.info.unitsPerEm = 1000
@@ -140,6 +184,7 @@ class CharacterWidget(QWidget):
painter.scale(factor, -factor)
painter.fillPath(glyph, Qt.black)
painter.restore()
+
class MainWindow(QMainWindow):
def __init__(self, font=Font()):
@@ -147,7 +192,8 @@ class MainWindow(QMainWindow):
self.font = font
self.scrollArea = QScrollArea()
- self.characterWidget = CharacterWidget(self.font)
+ squareSize = 48
+ self.characterWidget = CharacterWidget(self.font, squareSize, self)
self.scrollArea.setWidget(self.characterWidget)
# TODO: make shortcuts platform-independent
@@ -178,6 +224,20 @@ class MainWindow(QMainWindow):
helpMenu.addAction("&About", self.about)
helpMenu.addAction("About &Qt", QApplication.instance().aboutQt)
+
+ self.sqSizeSlider = QSlider(Qt.Horizontal)
+ self.sqSizeSlider.setMinimum(24)
+ self.sqSizeSlider.setMaximum(96)
+ #sz = self.sqSizeSlider.sizeHint()
+ #self.sqSizeSlider.setSize(.7*sz.width(), sz.height())
+ self.sqSizeSlider.setValue(squareSize)
+ self.sqSizeSlider.sliderMoved.connect(self._tipValue)
+ self.sqSizeSlider.valueChanged.connect(self._squareSizeChanged)
+ self.selectionLabel = QLabel()
+ self.selectionLabel.setFixedWidth(self.selectionLabel.fontMetrics().width('M') * 15)
+ self.characterWidget.characterSelected.connect(self._selectionChanged)
+ self.statusBar().addPermanentWidget(self.sqSizeSlider)
+ self.statusBar().addWidget(self.selectionLabel)
self.setCentralWidget(self.scrollArea)
self.setWindowTitle(os.path.basename(self.font.path.rstrip(os.sep)))
@@ -212,7 +272,23 @@ class MainWindow(QMainWindow):
def saveAndExit(self):
# TODO: check if font changed
QApplication.instance().quit()
+
+ def _tipValue(self):
+ text = str(self.sqSizeSlider.value())
+ QToolTip.showText(QCursor.pos(), text, self)
+
+ def _selectionChanged(self, count, glyph):
+ prefix = glyph + " " if count <= 1 else ""
+ self.selectionLabel.setText(prefix + "(" + str(count) + " selected)")
+
+ def _squareSizeChanged(self):
+ self.characterWidget.updateSize(self.sqSizeSlider.value())
+ """
+ def resizeEvent(self, event):
+ super(MainWindow, self).resizeEvent(event)
+ self.characterWidget.resizeEvent(event)
+ """
def fontInfo(self):
# If a window is already opened, bring it to the front, else make another one.
@@ -253,7 +329,7 @@ class MainWindow(QMainWindow):
from svgViewer import MainGfxWindow
if not (hasattr(self, 'glyphViewWindow') and self.glyphViewWindow.isVisible()):
# XXX: window collapses when passing self as parent...
- self.glyphViewWindow = MainGfxWindow(self.font["a"], self)
+ self.glyphViewWindow = MainGfxWindow(self.font, self.font["a"], self)
self.glyphViewWindow.show()
else:
self.glyphViewWindow.raise_()
@@ -274,7 +350,7 @@ if __name__ == '__main__':
representationFactories.registerAllFactories()
#with PyCallGraph(output=GraphvizOutput()):
app = QApplication(sys.argv)
- window = MainWindow(Font("C:\\Veloce.ufo"))
+ window = MainWindow(Font("C:\\CharterNova-Regular.ufo"))
window.resize(565, 430)
window.show()
sys.exit(app.exec_())
diff --git a/Lib/defconQt/glyphView.py b/Lib/defconQt/glyphView.py
deleted file mode 100644
index 70c9738..0000000
--- a/Lib/defconQt/glyphView.py
+++ /dev/null
@@ -1,6 +0,0 @@
-class MainSpaceWindow(QWidget):
- def __init__(self):
- self.scene = QGraphicsScene()
-
- layout = QVBoxLayout(self)
- layout.addWidget(self.scene) \ No newline at end of file
diff --git a/Lib/defconQt/spacecenter.py b/Lib/defconQt/spacecenter.py
index 61939b0..1295ca9 100644
--- a/Lib/defconQt/spacecenter.py
+++ b/Lib/defconQt/spacecenter.py
@@ -75,21 +75,22 @@ class GlyphsCanvas(QWidget):
painter.fillRect(0, 0, self.width(), self.height(), Qt.white)
painter.translate(self.padding, self.ptSize+self.font.info.descender*self.scale)
- cur_width = self.padding
+ cur_width = 0
for c in self.string:
- if c not in self.font: continue
+ glyph = self.font.unicodeData.glyphNameForUnicode(ord(c))
+ if glyph not in self.font: continue
# line wrapping
- if cur_width + self.font[c].width*self.scale + self.padding > self.width():
+ if cur_width + self.font[glyph].width*self.scale + self.padding > self.width():
painter.translate(-cur_width+self.padding, self.ptSize)
- cur_width = self.font[c].width*self.scale
+ cur_width = self.font[glyph].width*self.scale
else:
- cur_width += self.font[c].width*self.scale
- glyph = self.font[c].getRepresentation("defconQt.QPainterPath")
+ cur_width += self.font[glyph].width*self.scale
+ glyphPath = self.font[glyph].getRepresentation("defconQt.QPainterPath")
painter.save()
painter.scale(self.scale, -self.scale)
- painter.fillPath(glyph, Qt.black)
+ painter.fillPath(glyphPath, Qt.black)
painter.restore()
- painter.translate(self.font[c].width*self.scale, 0)
+ painter.translate(self.font[glyph].width*self.scale, 0)
'''
painter.setPen(
@@ -103,23 +104,24 @@ class GlyphsCanvas(QWidget):
'''
class SpaceTable(QTableWidget):
- def __init__(self, font, glyphs="", parent=None):
+ def __init__(self, font, string="", parent=None):
self.font = font
- self.glyphs = glyphs
- super(SpaceTable, self).__init__(4, len(self.glyphs), parent)
+ self.string = string
+ super(SpaceTable, self).__init__(4, len(self.string), parent)
data = [None, "Width", "Left", "Right"]
for index, item in enumerate(data):
cell = QTableWidgetItem(item)
# don't set ItemIsEditable
cell.setFlags(Qt.ItemIsEnabled)
self.setItem(index, 0, cell)
+ self.setColumnWidth(0, .6*self.columnWidth(0))
self.horizontalHeader().hide()
self.verticalHeader().hide()
# always show a scrollbar to fix layout
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.resizeRowsToContents()
self.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed))
- self.fillGlyphs(self.font, self.glyphs)
+ self.fillGlyphs(self.font, self.string)
self.setEditTriggers(QAbstractItemView.CurrentChanged)
def sizeHint(self):
@@ -130,24 +132,30 @@ class SpaceTable(QTableWidget):
height += margins.top() + margins.bottom()
return QSize(self.width(), height)
- def fillGlyphs(self, font, glyphs):
- '''
- def glyphTableWidgetItem(content):
+ def fillGlyphs(self, font, string):
+ def glyphTableWidgetItem(content, blockEdition=False):
+ if content is not None: content = str(content)
item = QTableWidgetItem(content)
- item.setTextAlignment(Qt.AlignCenter)
+ if content is None or blockEdition:
+ # don't set ItemIsEditable
+ item.setFlags(Qt.ItemIsEnabled)
+ #item.setTextAlignment(Qt.AlignCenter)
return item
- '''
- self.setColumnCount(len(glyphs)+1)
+
+ self.setColumnCount(len(string)+1)
dropped = 0
- for index, glyph in enumerate(glyphs):
+ for index, char in enumerate(string):
+ glyph = font.unicodeData.glyphNameForUnicode(ord(char))
+ i = index-dropped+1
if glyph not in font: dropped += 1; continue
# TODO: should glyph name edit really be permitted here?
# TODO: also find glyphs by /name or should be abstracted by input area or main object?
- self.setItem(0, index-dropped+1, QTableWidgetItem(font[glyph].name))
- self.setItem(1, index-dropped+1, QTableWidgetItem(str(font[glyph].width)))
- self.setItem(2, index-dropped+1, QTableWidgetItem(str(font[glyph].leftMargin)))
- self.setItem(3, index-dropped+1, QTableWidgetItem(str(font[glyph].rightMargin)))
- self.setColumnCount(len(glyphs)+1-dropped)
+ self.setItem(0, i, glyphTableWidgetItem(font[glyph].name, True))
+ self.setItem(1, i, glyphTableWidgetItem(font[glyph].width))
+ self.setItem(2, i, glyphTableWidgetItem(font[glyph].leftMargin))
+ self.setItem(3, i, glyphTableWidgetItem(font[glyph].rightMargin))
+ self.setColumnWidth(i, .7*self.columnWidth(i))
+ self.setColumnCount(len(string)+1-dropped)
def wheelEvent(self, event):
cur = self.horizontalScrollBar().value()
diff --git a/Lib/defconQt/svgViewer.py b/Lib/defconQt/svgViewer.py
index 0208cda..34fd07c 100644
--- a/Lib/defconQt/svgViewer.py
+++ b/Lib/defconQt/svgViewer.py
@@ -8,13 +8,13 @@ from PyQt5.QtSvg import QGraphicsSvgItem
class MainGfxWindow(QMainWindow):
- def __init__(self, glyph=None, parent=None):
+ def __init__(self, font=None, glyph=None, parent=None):
super(MainGfxWindow, self).__init__(parent)
self.currentPath = ''
self.view = SvgView()
- self.view.setGlyph(glyph)
+ self.view.setGlyph(font, glyph)
fileMenu = QMenu("&File", self)
openAction = fileMenu.addAction("&Open...")
@@ -153,14 +153,31 @@ class SvgView(QGraphicsView):
p.drawTiledPixmap(self.viewport().rect(),
self.backgroundBrush().texture())
p.restore()
-
- def drawPoints(self):
+
+ def addOutlines(self):
+ s = self.scene()
+ #painter = QPainter(self.viewport())
+ #painter.translate(0, self.height()*(1+self._font.info.descender/self._font.info.unitsPerEm))
+ #painter.scale(1, -1)
+ #painter.setRenderHint(QPainter.Antialiasing)
+ # outlines
+ path = self._glyph.getRepresentation("defconQt.QPainterPath")
+ s.addPath(path, brush=QBrush(Qt.black))
+ # components
+ '''
+ path = self._glyph.getRepresentation("defconAppKit.OnlyComponentsNSBezierPath")
+ self._componentFillColor.set()
+ path.fill()
+ '''
+
+ def addPoints(self):
# work out appropriate sizes and
# skip if the glyph is too small
- painter = QPainter(self.viewport())
- painter.translate(0, self.height())
- painter.scale(1, -1)
- #painter.translate(0, 400)
+ s = self.scene()
+ #painter = QPainter(self.viewport())
+ #painter.translate(0, self.height()*(1+self._font.info.descender/self._font.info.unitsPerEm))
+ #painter.scale(1, -1)
+ #painter.setRenderHint(QPainter.Antialiasing)
pointSize = 1000#self._impliedPointSize
if pointSize > 550:
startPointSize = 21
@@ -188,7 +205,9 @@ class SvgView(QGraphicsView):
points = []
# start point
if self._showOnCurvePoints and outlineData["startPoints"]:
- startWidth = startHeight = self.roundPosition(startPointSize * self._inverseScale)
+ startWidth = startHeight = self.roundPosition(startPointSize)# * self._inverseScale)
+ print("Morsay")
+ print(startWidth)
startHalf = startWidth / 2.0
path = QPainterPath()
for point, angle in outlineData["startPoints"]:
@@ -203,7 +222,8 @@ class SvgView(QGraphicsView):
path.addEllipse(x-startHalf, y-startHalf, startWidth, startHeight)
#self._startPointColor.set()
#path.fill()
- painter.fillPath(path, Qt.blue)
+ #painter.fillPath(path, Qt.blue)
+ s.addPath(path, brush=QBrush(Qt.blue))
# off curve
if self._showOffCurvePoints and outlineData["offCurvePoints"]:
# lines
@@ -213,30 +233,36 @@ class SvgView(QGraphicsView):
path.lineTo(*point2)
#self._bezierHandleColor.set()
#path.setLineWidth_(1.0 * self._inverseScale)
- painter.drawPath(path)
+ #painter.setPen(QPen(Qt.black, 1.0 * self._inverseScale))
+ # painter.drawPath(path)
+ s.addPath(path, Qt.black)
# points
- offWidth = offHeight = self.roundPosition(offCurvePointSize * self._inverseScale)
+ offWidth = offHeight = self.roundPosition(offCurvePointSize)# * self._inverseScale)
offHalf = offWidth / 2.0
path = QPainterPath()
for point in outlineData["offCurvePoints"]:
x, y = point["point"]
+ print(x,y)
+ print(offWidth, offHeight)
+ print()
points.append((x, y))
x = self.roundPosition(x - offHalf)
y = self.roundPosition(y - offHalf)
path.addEllipse(x, y, offWidth, offHeight)
- #path.setLineWidth_(3.0 * self._inverseScale)
+ #path.setLineWidth_(3.0#* self._inverseScale)
#self._pointStrokeColor.set()
- painter.drawPath(path)
+ #s.addPath(path, QPen(QBrush(Qt.darkGray), 3.0))
#self._backgroundColor.set()
- painter.fillPath(path, Qt.green)
+ s.addPath(path, brush=QBrush(Qt.green))
#self._pointColor.set()
#path.setLineWidth_(1.0 * self._inverseScale)
+ s.addPath(path, QPen(QBrush(Qt.black), 1.0))
#path.stroke()
# on curve
if self._showOnCurvePoints and outlineData["onCurvePoints"]:
- width = height = self.roundPosition(onCurvePointSize * self._inverseScale)
+ width = height = self.roundPosition(onCurvePointSize)# * self._inverseScale)
half = width / 2.0
- smoothWidth = smoothHeight = self.roundPosition(onCurveSmoothPointSize * self._inverseScale)
+ smoothWidth = smoothHeight = self.roundPosition(onCurveSmoothPointSize)# * self._inverseScale)
smoothHalf = smoothWidth / 2.0
path = QPainterPath()
for point in outlineData["onCurvePoints"]:
@@ -252,9 +278,11 @@ class SvgView(QGraphicsView):
path.addRect(x, y, width, height)
#self._pointStrokeColor.set()
#path.setLineWidth_(3.0 * self._inverseScale)
- painter.drawPath(path)
+ # painter.drawPath(path)
+ s.addPath(path, Qt.black)
#self._pointColor.set()
- painter.fillPath(path, Qt.red)
+ # painter.fillPath(path, Qt.red)
+ s.addPath(path, brush=QBrush(Qt.red))
# text
"""
if self._showPointCoordinates and coordinateSize:
@@ -281,9 +309,9 @@ class SvgView(QGraphicsView):
s = self.scene()
s.clear()
self.resetTransform()
- self.scale(1, -1)
+ #self.scale(1, -1)
- s.addPath(path, brush=QBrush(Qt.gray))
+ #s.addPath(path, brush=QBrush(Qt.gray))
#s.setSceneRect(path.boundingRect().adjusted(-10, -10, 10, 10))
def openFile(self, svg_file):
@@ -331,18 +359,26 @@ class SvgView(QGraphicsView):
s.setSceneRect(self.outlineItem.boundingRect().adjusted(-10, -10, 10, 10))
def roundPosition(self, value):
+ print("ROUND " + str(value))
value = value * self._scale
value = round(value) - .5
value = value * self._inverseScale
+ print("ROUND2 " + str(value))
return value
- def setGlyph(self, glyph):
+ def setGlyph(self, font, glyph):
+ self._font = font
self._glyph = glyph
self._inverseScale = 0.1
- self._scale = 1.0
+ self._scale = 10
self._showOffCurvePoints = True
self._showOnCurvePoints = True
- self.openPath(glyph.getRepresentation("defconQt.QPainterPath"))
+
+ self.translate(0, self.height()*(1+self._font.info.descender/self._font.info.unitsPerEm))
+ self.scale(1, -1)
+ self.addOutlines()
+ self.addPoints()
+ #self.openPath(glyph.getRepresentation("defconQt.QPainterPath"))
def setRenderer(self, renderer):
self.renderer = renderer
@@ -380,7 +416,8 @@ class SvgView(QGraphicsView):
p.drawImage(0, 0, self.image)
else:
super(SvgView, self).paintEvent(event)
- self.drawPoints()
+ #self.drawOutlines()
+ #self.drawPoints()
def wheelEvent(self, event):
factor = pow(1.2, event.angleDelta().y() / 120.0)
diff --git a/Lib/defconQt/syntaxhighlighter.py b/Lib/defconQt/syntaxhighlighter.py
index 95c538a..4f48e81 100644
--- a/Lib/defconQt/syntaxhighlighter.py
+++ b/Lib/defconQt/syntaxhighlighter.py
@@ -1,7 +1,7 @@
from PyQt5.QtCore import QFile, QRegExp, Qt
-from PyQt5.QtGui import QColor, QFont, QSyntaxHighlighter, QTextCharFormat
+from PyQt5.QtGui import QColor, QFont, QPainter, QSyntaxHighlighter, QTextCharFormat
from PyQt5.QtWidgets import (QApplication, QFileDialog, QMainWindow, QMenu,
- QMessageBox, QTextEdit)
+ QMessageBox, QPlainTextEdit, QWidget)
class MainEditWindow(QMainWindow):
def __init__(self, font=None, parent=None):
@@ -58,7 +58,18 @@ class MainEditWindow(QMainWindow):
fileMenu.addAction("&Save...", self.save, "Ctrl+S")
fileMenu.addAction("E&xit", self.quit, "Ctrl+Q")
-class TextEditor(QTextEdit):
+class LineNumberArea(QWidget):
+ def __init__(self,editor):
+ self.codeEditor = editor
+ super(LineNumberArea, self).__init__(editor)
+
+ def sizeHint(self):
+ return QSize(self.codeEditor.lineNumberAreaWidth(), 0)
+
+ def paintEvent(self, event):
+ self.codeEditor.lineNumberAreaPaintEvent(event)
+
+class TextEditor(QPlainTextEdit):
def __init__(self, text=None, parent=None):
super(TextEditor, self).__init__(parent)
font = QFont()
@@ -66,11 +77,13 @@ class TextEditor(QTextEdit):
font.setPointSize(10)
font.setFixedPitch(True)
- self.setAcceptRichText(False)
self.setPlainText(text)
self.setFont(font)
self.highlighter = Highlighter(self.document())
+ self.lineNumbers = LineNumberArea(self)
+ self.blockCountChanged.connect(self.updateLineNumberAreaWidth)
+ self.updateRequest.connect(self.updateLineNumberArea)
def setFontParams(self, family='CamingoCode', ptSize=10, isMono=True):
font = QFont()
@@ -81,6 +94,59 @@ class TextEditor(QTextEdit):
def write(self, features):
features.text = self.toPlainText()
+
+ def lineNumberAreaPaintEvent(self, event):
+ painter = QPainter(self.lineNumbers)
+ painter.fillRect(event.rect(), QColor(230, 230, 230))
+ d = event.rect().topRight()
+ a = event.rect().bottomRight()
+ painter.setPen(Qt.darkGray)
+ painter.drawLine(d.x(), d.y(), a.x(), a.y())
+ painter.setPen(Qt.black)
+ painter.setFont(self.font())
+
+ block = self.firstVisibleBlock()
+ blockNumber = block.blockNumber();
+ top = int(self.blockBoundingGeometry(block).translated(self.contentOffset()).top())
+ bottom = top + int(self.blockBoundingRect(block).height())
+
+ while block.isValid() and top <= event.rect().bottom():
+ if block.isVisible() and bottom >= event.rect().top():
+ number = str(blockNumber + 1)
+ painter.drawText(4, top, self.lineNumbers.width() - 8,
+ self.fontMetrics().height(),
+ Qt.AlignRight, number)
+ block = block.next()
+ top = bottom
+ bottom = top + int(self.blockBoundingRect(block).height())
+ blockNumber += 1
+
+ def lineNumberAreaWidth(self):
+ digits = 1
+ top = max(1, self.blockCount())
+ while (top >= 10):
+ top /= 10
+ digits += 1
+ return 10 + self.fontMetrics().width('9') * digits
+
+ def updateLineNumberArea(self, rect, dy):
+
+ if dy:
+ self.lineNumbers.scroll(0, dy);
+ else:
+ self.lineNumbers.update(0, rect.y(),
+ self.lineNumbers.width(), rect.height())
+
+ if rect.contains(self.viewport().rect()):
+ self.updateLineNumberAreaWidth(0)
+
+ def updateLineNumberAreaWidth(self, newBlockCount):
+ self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0)
+
+ def resizeEvent(self, event):
+ super(TextEditor, self).resizeEvent(event)
+ cr = self.contentsRect()
+ self.lineNumbers.setGeometry(cr.left(), cr.top(), self.lineNumberAreaWidth(), cr.height())
'''
def keyPressEvent(self, event):