aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrien Tétar2015-05-27 21:21:58 +0200
committerAdrien Tétar2015-05-27 21:21:58 +0200
commit82a6fe3e119bbc52f76da41c4e430f59ee240d11 (patch)
tree393787b59ab0c1761475a8a99f5ddeeaa0ba93b6
parent29ccad19586ff9592ae6199255dc2c9b702a65e7 (diff)
downloadtrufont-82a6fe3e119bbc52f76da41c4e430f59ee240d11.tar.bz2
fontView: use cannedDesign descriptor, read markColor, spaceCenter: add single-line capatibility, glyphView: rudimentary points scaling
-rw-r--r--Lib/defconQt/fontView.py34
-rw-r--r--Lib/defconQt/glyphView.py55
-rw-r--r--Lib/defconQt/icons_db.qrc (renamed from Lib/defconQt/fontView.qrc)1
-rw-r--r--Lib/defconQt/resources/ic_settings_24px.svg1
-rw-r--r--Lib/defconQt/resources/ic_settings_48px.svg1
-rw-r--r--Lib/defconQt/spacecenter.py105
6 files changed, 156 insertions, 41 deletions
diff --git a/Lib/defconQt/fontView.py b/Lib/defconQt/fontView.py
index 3483ec0..3b0242f 100644
--- a/Lib/defconQt/fontView.py
+++ b/Lib/defconQt/fontView.py
@@ -16,6 +16,9 @@ glyphSortDescriptors = [
dict(type="suffix", allowPseudoUnicode=True),
dict(type="decompositionBase", allowPseudoUnicode=True)
]
+cannedDesign = [
+ dict(type="cannedDesign", allowPseudoUnicode=True)
+]
cellGridColor = QColor(130, 130, 130)
cellHeaderBaseColor = QColor(230, 230, 230)
@@ -34,7 +37,8 @@ class CharacterWidget(QWidget):
super(CharacterWidget, self).__init__(parent)
self.font = font
- self.glyphs = [font[k] for k in font.unicodeData.sortGlyphNames(font.keys(), glyphSortDescriptors)]
+ #self.glyphs = [font[k] for k in font.unicodeData.sortGlyphNames(font.keys(), glyphSortDescriptors)]
+ self.glyphs = [font[k] for k in font.unicodeData.sortGlyphNames(font.keys(), cannedDesign)]
self.scrollArea = scrollArea
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.squareSize = squareSize
@@ -156,6 +160,7 @@ class CharacterWidget(QWidget):
else:
super(CharacterWidget, self).mousePressEvent(event)
+ # TODO: see if more of this process can be delegated to a factory
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
@@ -185,6 +190,9 @@ class CharacterWidget(QWidget):
gradient = QLinearGradient(0, 0, 0, GlyphCellHeaderHeight)
gradient.setColorAt(0.0, cellHeaderBaseColor)
gradient.setColorAt(1.0, cellHeaderLineColor)
+ #markGradient = QRadialGradient(self.squareSize/2, GlyphCellHeaderHeight/2,
+ # self.squareSize-GlyphCellHeaderHeight, self.squareSize/2, self.squareSize)
+ markGradient = QLinearGradient(0, 0, 0, self.squareSize-GlyphCellHeaderHeight)
for row in range(beginRow, endRow + 1):
for column in range(beginColumn, endColumn + 1):
@@ -195,6 +203,19 @@ class CharacterWidget(QWidget):
painter.translate(column * self.squareSize, row * self.squareSize)
# background
painter.fillRect(0, 0, self.squareSize, self.squareSize, Qt.white)
+ glyph = self.glyphs[key]
+ if "public.markColor" in glyph.lib:
+ colorStr = glyph.lib["public.markColor"].split(",")
+ if len(colorStr) == 4:
+ comp = []
+ for c in colorStr:
+ comp.append(float(c.strip()))
+ markColor = QColor.fromRgbF(*comp)
+ markGradient.setColorAt(1.0, markColor)
+ markGradient.setColorAt(0.0, markColor.lighter(125))
+ painter.fillRect(0, GlyphCellHeaderHeight, self.squareSize,
+ self.squareSize - GlyphCellHeaderHeight, QBrush(markGradient))
+
# header gradient
painter.fillRect(0, 0, self.squareSize,
GlyphCellHeaderHeight, QBrush(gradient))
@@ -352,14 +373,17 @@ class MainWindow(QMainWindow):
def closeEvent(self, event):
if self.font.dirty:
- closeDialog = QMessageBox(QMessageBox.Question, "Save your work?", "Will you save, dear",
- QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel, self)
+ title = "Me"
+ body = "%s%s%s" % ("Do you want to save the changes you made to “", os.path.basename(self.font.path.rstrip(os.sep)), "”?")
+ closeDialog = QMessageBox(QMessageBox.Question, title, body,
+ QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel, self)
+ closeDialog.setInformativeText("Your changes will be lost if you don’t save them.")
closeDialog.setModal(True)
ret = closeDialog.exec_()
- if ret == QMessageBox.Yes:
+ if ret == QMessageBox.Save:
self.saveFile()
event.accept()
- elif ret == QMessageBox.No:
+ elif ret == QMessageBox.Discard:
event.accept()
else: #if ret == QMessageBox.Cancel:
event.ignore()
diff --git a/Lib/defconQt/glyphView.py b/Lib/defconQt/glyphView.py
index fda4314..a4ce3bf 100644
--- a/Lib/defconQt/glyphView.py
+++ b/Lib/defconQt/glyphView.py
@@ -388,34 +388,27 @@ class GlyphView(QGraphicsView):
self._fillColor = QColor.fromRgbF(0, 0, 0, .4)#Qt.gray
self._componentFillColor = QColor.fromRgbF(.2, .2, .3, .4)#Qt.darkGray
+ self.setBackgroundBrush(QBrush(Qt.lightGray))
self.setScene(GlyphScene(self))
#self.scene().setSceneRect(0, self._font.info.ascender, self._glyph.width, self._font.info.unitsPerEm)
+
self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
self.setDragMode(QGraphicsView.RubberBandDrag)
- # This rewinds view when scrolling, needed for check-board background
- #self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
self.setRenderHint(QPainter.Antialiasing)
- self.translate(0, self.height()*(1+self._font.info.descender/self._font.info.unitsPerEm))
+ #self.translate(0, self.height()*(1+self._font.info.descender/self._font.info.unitsPerEm))
self.scale(1, -1)
self.addBackground()
self.addBlues()
self.addOutlines()
self.addPoints()
-
- # Prepare background check-board pattern.
- """
- tilePixmap = QPixmap(64, 64)
- tilePixmap.fill(Qt.white)
- tilePainter = QPainter(tilePixmap)
- color = QColor(220, 220, 220)
- tilePainter.fillRect(0, 0, 32, 32, color)
- tilePainter.fillRect(32, 32, 32, 32, color)
- tilePainter.end()
- """
-
- #self.setBackgroundBrush(QBrush(tilePixmap))
+
+
+ #self.fitInView(0, self._font.info.descender, self._glyph.width, self._font.info.unitsPerEm, Qt.KeepAspectRatio)
+ #sc = self.height()/self.scene().height()
+ #self.scale(sc, sc);
+ self.scene().setSceneRect(-1500, -1500, 3000, 3000)
def _glyphChanged(self, event):
pass
@@ -458,7 +451,9 @@ class GlyphView(QGraphicsView):
def addBackground(self):
s = self.scene()
- s.addRect(QRectF(self.viewport().rect()), QPen(Qt.NoPen), QBrush(self._backgroundColor))
+ width = self._glyph.width
+ item = s.addRect(0, self._font.info.descender, width, self._font.info.unitsPerEm, QPen(Qt.NoPen), QBrush(self._backgroundColor))
+ self.centerOn(item)
def addBlues(self):
s = self.scene()
@@ -674,17 +669,29 @@ class GlyphView(QGraphicsView):
#self._calcScale()
#self._setFrame()
self.scale(factor, factor)
- '''
+
+ scale = self.transform().m11()
+ if scale < .3 or scale > 1: scale = 1
+ offCurvePointSize = 5 / scale
+ onCurvePointSize = 6 / scale
+ onCurveSmoothPointSize = 7 / scale
for item in self.scene().items():
if isinstance(item, OnCurvePointItem):
path = QPainterPath()
- onCurvePointSize = 10 / self.transform().m11()
- width = height = self.roundPosition(onCurvePointSize)# * self._inverseScale)
- half = width / 2.0
- path.addEllipse(-half, -half, width, height)
+ if item._isSmooth:
+ width = height = self.roundPosition(onCurveSmoothPointSize)# * self._inverseScale)
+ half = width / 2.0
+ path.addEllipse(-half, -half, width, height)
+ else:
+ width = height = self.roundPosition(onCurvePointSize)# * self._inverseScale)
+ half = width / 2.0
+ path.addRect(-half, -half, width, height)
item.setPath(path)
- #item.setTransform(self.transform().inverted()[0])
- '''
+ elif isinstance(item, OffCurvePointItem):
+ width = height = self.roundPosition(offCurvePointSize)# * self._inverseScale)
+ half = width / 2.0
+ item.setRect(-half, -half, width, height)
+
self.update()
event.accept()
diff --git a/Lib/defconQt/fontView.qrc b/Lib/defconQt/icons_db.qrc
index 8e45d53..5973849 100644
--- a/Lib/defconQt/fontView.qrc
+++ b/Lib/defconQt/icons_db.qrc
@@ -1,6 +1,7 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>resources/icon.png</file>
+ <file>resources/ic_settings_24px.svg</file>
</qresource>
</RCC>
diff --git a/Lib/defconQt/resources/ic_settings_24px.svg b/Lib/defconQt/resources/ic_settings_24px.svg
new file mode 100644
index 0000000..a09d544
--- /dev/null
+++ b/Lib/defconQt/resources/ic_settings_24px.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/></svg> \ No newline at end of file
diff --git a/Lib/defconQt/resources/ic_settings_48px.svg b/Lib/defconQt/resources/ic_settings_48px.svg
new file mode 100644
index 0000000..7a01c33
--- /dev/null
+++ b/Lib/defconQt/resources/ic_settings_48px.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path d="M38.86 25.95c.08-.64.14-1.29.14-1.95s-.06-1.31-.14-1.95l4.23-3.31c.38-.3.49-.84.24-1.28l-4-6.93c-.25-.43-.77-.61-1.22-.43l-4.98 2.01c-1.03-.79-2.16-1.46-3.38-1.97L29 4.84c-.09-.47-.5-.84-1-.84h-8c-.5 0-.91.37-.99.84l-.75 5.3c-1.22.51-2.35 1.17-3.38 1.97L9.9 10.1c-.45-.17-.97 0-1.22.43l-4 6.93c-.25.43-.14.97.24 1.28l4.22 3.31C9.06 22.69 9 23.34 9 24s.06 1.31.14 1.95l-4.22 3.31c-.38.3-.49.84-.24 1.28l4 6.93c.25.43.77.61 1.22.43l4.98-2.01c1.03.79 2.16 1.46 3.38 1.97l.75 5.3c.08.47.49.84.99.84h8c.5 0 .91-.37.99-.84l.75-5.3c1.22-.51 2.35-1.17 3.38-1.97l4.98 2.01c.45.17.97 0 1.22-.43l4-6.93c.25-.43.14-.97-.24-1.28l-4.22-3.31zM24 31c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></svg> \ No newline at end of file
diff --git a/Lib/defconQt/spacecenter.py b/Lib/defconQt/spacecenter.py
index 8fa776d..5aa755f 100644
--- a/Lib/defconQt/spacecenter.py
+++ b/Lib/defconQt/spacecenter.py
@@ -1,30 +1,39 @@
from PyQt5.QtCore import QAbstractTableModel, QEvent, QSize, Qt
-from PyQt5.QtGui import (QBrush, QColor, QFont, QKeySequence, QLinearGradient, QPainter,
+from PyQt5.QtGui import (QBrush, QColor, QFont, QIcon, QKeySequence, QLinearGradient, QPainter,
QPainterPath, QPalette, QPen)
-from PyQt5.QtWidgets import (QAbstractItemView, QApplication, QComboBox, QGridLayout, QLabel, QLineEdit,
- QMainWindow, QScrollArea, QStyledItemDelegate, QTableView, QTableWidget, QTableWidgetItem, QVBoxLayout, QSizePolicy, QSpinBox, QToolBar, QWidget)
+from PyQt5.QtWidgets import (QAbstractItemView, QActionGroup, QApplication, QComboBox, QGridLayout, QLabel, QLineEdit,
+ QMainWindow, QMenu, QPushButton, QScrollArea, QStyledItemDelegate, QTableView, QTableWidget, QTableWidgetItem, QVBoxLayout, QSizePolicy, QSpinBox, QToolBar, QWidget)
defaultPointSize = 150
class MainSpaceWindow(QWidget):
- def __init__(self, font, string="Hello World", pointSize=defaultPointSize, parent=None):
+ def __init__(self, font, string=None, pointSize=defaultPointSize, parent=None):
super(MainSpaceWindow, self).__init__(parent, Qt.Window)
+ if string is None:
+ from getpass import getuser
+ try:
+ string = getuser()
+ except:
+ string = "World"
+ string = "%s%s" % ("Hello ", string)
self.font = font
self.glyphs = []
self._subscribeToGlyphsText(string)
self.toolbar = FontToolBar(string, pointSize, self)
- self.canvas = GlyphsCanvas(self.font, self.glyphs, pointSize, self)
+ self.scrollArea = QScrollArea(self)
+ self.canvas = GlyphsCanvas(self.font, self.glyphs, self.scrollArea, pointSize, self)
+ self.scrollArea.setWidget(self.canvas)
self.table = SpaceTable(self.glyphs, self)
layout = QVBoxLayout(self)
layout.addWidget(self.toolbar)
- layout.addWidget(self.canvas)
+ layout.addWidget(self.scrollArea)
layout.addWidget(self.table)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
self.setLayout(layout)
- self.resize(600,500)
+ self.resize(600, 500)
self.toolbar.comboBox.currentIndexChanged[str].connect(self.canvas._pointSizeChanged)
self.toolbar.textField.textEdited.connect(self._textChanged)
@@ -139,6 +148,10 @@ class MainSpaceWindow(QWidget):
# set the records into the view
self.canvas._glyphsChanged(self.glyphs)
self.table._glyphsChanged(self.glyphs)
+
+ def resizeEvent(self, event):
+ if self.isVisible(): self.canvas._sizeEvent(event)
+ super(MainSpaceWindow, self).resizeEvent(event)
pointSizes = [50, 75, 100, 125, 150, 200, 250, 300, 350, 400, 450, 500]
@@ -152,11 +165,35 @@ class FontToolBar(QToolBar):
self.comboBox.addItem(str(p))
self.comboBox.lineEdit().setText(str(pointSize))
+ self.configBar = QPushButton(self)
+ self.configBar.setFlat(True)
+ self.configBar.setIcon(QIcon("C:\\Users\\Adrien\\Downloads\\defconQt\\Lib\\defconQt\\resources\\ic_settings_24px.svg"))
+ self.configBar.setStyleSheet("padding: 2px 0px; padding-right: 10px");
+ self.toolsMenu = QMenu(self)
+ wrapLines = self.toolsMenu.addAction("Wrap lines", self.wrapLines)
+ wrapLines.setCheckable(True)
+ noWrapLines = self.toolsMenu.addAction("No wrap", self.noWrapLines)
+ noWrapLines.setCheckable(True)
+
+ wrapLinesGroup = QActionGroup(self)
+ wrapLinesGroup.addAction(wrapLines)
+ wrapLinesGroup.addAction(noWrapLines)
+ wrapLines.setChecked(True)
+ #self.toolsMenu.setActiveAction(wrapLines)
+ self.configBar.setMenu(self.toolsMenu)
+
self.addWidget(self.textField)
self.addWidget(self.comboBox)
+ self.addWidget(self.configBar)
+
+ def wrapLines(self):
+ self.parent().canvas.setWrapLines(True)
+
+ def noWrapLines(self):
+ self.parent().canvas.setWrapLines(False)
class GlyphsCanvas(QWidget):
- def __init__(self, font, glyphs, pointSize=defaultPointSize, parent=None):
+ def __init__(self, font, glyphs, scrollArea, pointSize=defaultPointSize, parent=None):
super(GlyphsCanvas, self).__init__(parent)
self.ascender = font.info.ascender
@@ -169,12 +206,33 @@ class GlyphsCanvas(QWidget):
self.ptSize = pointSize
self.calculateScale()
self.padding = 10
+
+ self._wrapLines = True
+ self.scrollArea = scrollArea
+ self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+ self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
+ self.resize(581, 400)
def calculateScale(self):
scale = self.ptSize / self.upm
if scale < .01: scale = 0.01
self.scale = scale
+ def setWrapLines(self, wrapLines):
+ if self._wrapLines == wrapLines: return
+ self._wrapLines = wrapLines
+ if self._wrapLines:
+ sw = self.scrollArea.verticalScrollBar().width() + self.scrollArea.contentsMargins().right()
+ self.resize(self.parent().parent().parent().width() - sw, self.height())
+ self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+ self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
+ else:
+ sh = self.scrollArea.horizontalScrollBar().height() + self.scrollArea.contentsMargins().bottom()
+ self.resize(self.width(), self.parent().parent().parent().height() - sh)
+ self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+ self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
+ self.update()
+
def _pointSizeChanged(self, pointSize):
self.ptSize = int(pointSize)
self.calculateScale()
@@ -184,6 +242,14 @@ class GlyphsCanvas(QWidget):
self.glyphs = newGlyphs
self.update()
+ def _sizeEvent(self, event):
+ if self._wrapLines:
+ sw = self.scrollArea.verticalScrollBar().width() + self.scrollArea.contentsMargins().right()
+ self.resize(event.size().width() - sw, self.height())
+ else:
+ sh = self.scrollArea.horizontalScrollBar().height() + self.scrollArea.contentsMargins().bottom()
+ self.resize(self.width(), event.size().height() - sh)
+
# if we have a cell clicked in and we click on the canvas,
# give focus to the canvas in order to quit editing
# TODO: Focus on individual chars and show BBox + active cell (see how rf does active cells)
@@ -200,7 +266,8 @@ class GlyphsCanvas(QWidget):
# TODO: send notification to parent and do all the fuss there
self._pointSizeChanged(newPointSize)
- comboBox = self.parent().toolbar.comboBox
+ # TODO: ugh…
+ comboBox = self.parent().parent().parent().toolbar.comboBox
comboBox.blockSignals(True)
comboBox.setEditText(str(newPointSize))
comboBox.blockSignals(False)
@@ -210,15 +277,17 @@ class GlyphsCanvas(QWidget):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.fillRect(0, 0, self.width(), self.height(), Qt.white)
- # TODO: should padding be added for the right boundary as well? I'd say no but not sure
painter.translate(self.padding, self.padding+self.ascender*self.scale)
cur_width = 0
+ lines = 1
for glyph in self.glyphs:
# line wrapping
- if cur_width + glyph.width*self.scale + self.padding > self.width():
+ # TODO: should padding be added for the right boundary as well? I'd say no but not sure
+ if self._wrapLines and cur_width + glyph.width*self.scale + self.padding > self.width():
painter.translate(-cur_width, self.ptSize)
cur_width = glyph.width*self.scale
+ lines += 1
else:
cur_width += glyph.width*self.scale
glyphPath = glyph.getRepresentation("defconQt.QPainterPath")
@@ -227,8 +296,15 @@ class GlyphsCanvas(QWidget):
painter.fillPath(glyphPath, Qt.black)
painter.restore()
painter.translate(glyph.width*self.scale, 0)
+
+ scrollMargins = self.scrollArea.contentsMargins()
+ innerHeight = self.scrollArea.height() - scrollMargins.top() - scrollMargins.bottom()
+ innerWidth = self.scrollArea.width() - scrollMargins.left() - scrollMargins.right()
+ width = max(innerWidth, cur_width+self.padding*2) if not self._wrapLines else self.width()
+ self.resize(width, max(innerHeight, lines*self.ptSize))
class GlyphCellItemDelegate(QStyledItemDelegate):
+ # TODO: implement =... lexer
def eventFilter(self, editor, event):
if event.type() == QEvent.KeyPress:
chg = None
@@ -240,8 +316,13 @@ class GlyphCellItemDelegate(QStyledItemDelegate):
elif not event.key() == Qt.Key_Return:
return False
if chg is not None:
- if event.modifiers() & Qt.AltModifier:
+ modifiers = event.modifiers()
+ if modifiers & Qt.AltModifier:
return False
+ elif modifiers & Qt.ShiftModifier:
+ chg *= 10
+ if modifiers & Qt.ControlModifier:
+ chg *= 10
cur = int(editor.text())
editor.setText(str(cur+chg))
self.commitData.emit(editor)