aboutsummaryrefslogtreecommitdiffstats
path: root/Lib/defconQt/charmap.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/defconQt/charmap.py')
-rw-r--r--Lib/defconQt/charmap.py339
1 files changed, 339 insertions, 0 deletions
diff --git a/Lib/defconQt/charmap.py b/Lib/defconQt/charmap.py
new file mode 100644
index 0000000..0032a0f
--- /dev/null
+++ b/Lib/defconQt/charmap.py
@@ -0,0 +1,339 @@
+#!/usr/bin/env python
+
+
+#############################################################################
+##
+## Copyright (C) 2013 Riverbank Computing Limited.
+## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+##
+## This file is part of the examples of PyQt.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+## the names of its contributors may be used to endorse or promote
+## products derived from this software without specific prior written
+## permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import representationFactories
+import unicodedata
+
+from defcon import Font
+from PyQt5.QtCore import pyqtSignal, QSize, Qt
+from PyQt5.QtGui import (QClipboard, QFont, QFontDatabase, QFontMetrics,
+ QPainter)
+from PyQt5.QtWidgets import (QApplication, QCheckBox, QComboBox, QFontComboBox,
+ QHBoxLayout, QLabel, QLineEdit, QMainWindow, QPushButton, QScrollArea,
+ QToolTip, QVBoxLayout, QWidget)
+
+glyphSortDescriptors = [
+ dict(type="alphabetical", allowPseudoUnicode=True),
+ dict(type="category", allowPseudoUnicode=True),
+ dict(type="unicode", allowPseudoUnicode=True),
+ dict(type="script", allowPseudoUnicode=True),
+ dict(type="suffix", allowPseudoUnicode=True),
+ dict(type="decompositionBase", allowPseudoUnicode=True)
+]
+
+class CharacterWidget(QWidget):
+
+ characterSelected = pyqtSignal(str)
+
+ def __init__(self, font, 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.columns = 11
+ self.lastKey = -1
+# self.setMouseTracking(True)
+
+ def updateFont(self, fontFamily):
+ self.displayFont.setFamily(fontFamily)
+ self.squareSize = max(24, QFontMetrics(self.displayFont).xHeight() * 3)
+ self.adjustSize()
+ self.update()
+
+ def updateSize(self, fontSize):
+# fontSize, _ = fontSize.toInt()
+ self.displayFont.setPointSize(int(fontSize))
+ self.squareSize = max(24, QFontMetrics(self.displayFont).xHeight() * 3)
+ self.adjustSize()
+ self.update()
+
+ def updateStyle(self, fontStyle):
+ fontDatabase = QFontDatabase()
+ oldStrategy = self.displayFont.styleStrategy()
+ self.displayFont = fontDatabase.font(self.displayFont.family(),
+ fontStyle, self.displayFont.pointSize())
+ self.displayFont.setStyleStrategy(oldStrategy)
+ self.squareSize = max(24, QFontMetrics(self.displayFont).xHeight() * 3)
+ self.adjustSize()
+ self.update()
+
+ def updateFontMerging(self, enable):
+ if enable:
+ self.displayFont.setStyleStrategy(QFont.PreferDefault)
+ else:
+ self.displayFont.setStyleStrategy(QFont.NoFontMerging)
+ self.adjustSize()
+ self.update()
+
+ def sizeHint(self):
+ return QSize(self.columns * self.squareSize,
+ (65536 / self.columns) * self.squareSize)
+
+ '''
+ def mouseMoveEvent(self, event):
+ widgetPosition = self.mapFromGlobal(event.globalPos())
+ key = (widgetPosition.y() // self.squareSize) * self.columns + widgetPosition.x() // self.squareSize
+
+ # http://stackoverflow.com/questions/6598554/is-there-any-way-to-insert-qpixmap-object-in-html
+ text = '<p>Character: <span style="font-size: 24pt; font-family: %s">%s</span><p>Value: 0x%x' % (QFont().family(), self._chr(key), key)
+ QToolTip.showText(event.globalPos(), text, self)
+ '''
+
+ 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)
+
+ if unicodedata.category(key_ch) != 'Cn':
+ self.characterSelected.emit(key_ch)
+ self.update()
+ else:
+ super(CharacterWidget, self).mousePressEvent(event)
+
+ def paintEvent(self, event):
+ painter = QPainter(self)
+ painter.setRenderHint(QPainter.Antialiasing)
+ painter.fillRect(event.rect(), Qt.white)
+ #painter.setFont(self.displayFont)
+
+ redrawRect = event.rect()
+ beginRow = redrawRect.top() // self.squareSize
+ endRow = redrawRect.bottom() // self.squareSize
+ beginColumn = redrawRect.left() // self.squareSize
+ endColumn = redrawRect.right() // self.squareSize
+
+ painter.setPen(Qt.gray)
+ for row in range(beginRow, endRow + 1):
+ for column in range(beginColumn, endColumn + 1):
+ painter.drawRect(column * self.squareSize,
+ row * self.squareSize, self.squareSize,
+ self.squareSize)
+
+# fontMetrics = QFontMetrics(self.displayFont)
+# painter.setPen(Qt.black)
+
+
+ """
+ draw = self.displayFont["a"].getRepresentation("defconQt.QPainterPath")
+ painter.save()
+ painter.setBrushOrigin(50, 150)
+# painter.scale(1.0, -1.0)
+# painter.translate(0,-self.squareSize)
+# p_x,p_y,p_w,p_h = draw.controlPointRect().getRect()
+# measure = max(p_w, p_h)
+# painter.scale(measure/self.squareSize, measure/self.squareSize)
+ painter.fillPath(draw, Qt.black)
+ painter.restore()
+ """
+ for row in range(beginRow, endRow + 1):
+ for column in range(beginColumn, endColumn + 1):
+ key = row * self.columns + column
+ x,y,w,h = column * self.squareSize, row * self.squareSize, self.squareSize, self.squareSize
+# painter.setClipRect(x,y,w,h)
+
+ if key == self.lastKey:
+ painter.fillRect(column * self.squareSize + 1,
+ row * self.squareSize + 1, self.squareSize - 2,
+ self.squareSize - 2, Qt.red)
+
+ key_ch = str(self._chr(key))
+# painter.drawText(column * self.squareSize + (self.squareSize / 2) - fontMetrics.width(key_ch) / 2,
+# row * self.squareSize + 4 + fontMetrics.ascent(),
+# key_ch)
+# print(key)
+ if key > len(self.glyphs)-1: break
+ glyph = self.glyphs[key].getRepresentation("defconQt.QPainterPath")
+# if key_ch not in self.displayFont: continue
+# glyph = self.displayFont[key_ch].getRepresentation("defconQt.QPainterPath") # , width=self.squareSize, height=self.squareSize
+ # When need to move the painter so that the path draws at the right place
+ print(glyph)
+# p_x,p_y,p_w,p_h = glyph.controlPointRect().getRect()
+# print(p_h, h)
+ painter.save()
+ if self.font.info.unitsPerEm > 0: factor = self.squareSize/(self.font.info.unitsPerEm*(1+2*.125))
+ if factor != 0: print(factor)
+ x_offset = (self.squareSize-self.glyphs[key].width*factor)/2
+ if x_offset < 0:
+ factor *= 1+2*x_offset/(self.glyphs[key].width*factor)
+ x_offset = 0
+ y_offset = self.font.info.descender*factor
+ print(self.glyphs[key].width)
+ print("xo: "+str(x_offset))
+ painter.translate(column * self.squareSize + x_offset, row * self.squareSize + self.squareSize + y_offset)
+# painter.setBrushOrigin((self.squareSize-self.glyphs[key].width)/2,self.font.info.descender)
+# painter.translate(column * self.squareSize + (self.squareSize / 2) - self.glyphs[key].width / 2,
+# row * self.squareSize + 4 + self.displayFont['hhea'].ascent)
+# painter.translate(p_x-x, p_y-y)
+# painter.scale(1.0, -1.0)
+# painter.translate(0,-self.squareSize)
+ painter.scale(factor, -factor)
+ painter.fillPath(glyph, Qt.black)
+ painter.restore()
+
+ @staticmethod
+ def _chr(codepoint):
+ try:
+ # Python v2.
+ return unichr(codepoint)
+ except NameError:
+ # Python v3.
+ return chr(codepoint)
+
+class MainWindow(QMainWindow):
+ def __init__(self, font=Font()):
+ super(MainWindow, self).__init__()
+
+ centralWidget = QWidget()
+
+ self.font = font
+
+ fontLabel = QLabel("Font:")
+ self.fontCombo = QFontComboBox()
+ sizeLabel = QLabel("Size:")
+ self.sizeCombo = QComboBox()
+ styleLabel = QLabel("Style:")
+ self.styleCombo = QComboBox()
+ fontMergingLabel = QLabel("Automatic Font Merging:")
+ self.fontMerging = QCheckBox()
+ self.fontMerging.setChecked(True)
+
+ self.scrollArea = QScrollArea()
+ self.characterWidget = CharacterWidget(self.font)
+ self.scrollArea.setWidget(self.characterWidget)
+
+ self.findStyles(self.fontCombo.currentFont())
+ self.findSizes(self.fontCombo.currentFont())
+
+ self.lineEdit = QLineEdit()
+ clipboardButton = QPushButton("&To clipboard")
+
+ self.clipboard = QApplication.clipboard()
+
+ self.fontCombo.currentFontChanged.connect(self.findStyles)
+ self.fontCombo.activated[str].connect(self.characterWidget.updateFont)
+ self.styleCombo.activated[str].connect(self.characterWidget.updateStyle)
+ self.sizeCombo.currentIndexChanged[str].connect(self.characterWidget.updateSize)
+ self.characterWidget.characterSelected.connect(self.insertCharacter)
+ clipboardButton.clicked.connect(self.updateClipboard)
+
+ controlsLayout = QHBoxLayout()
+ controlsLayout.addWidget(fontLabel)
+ controlsLayout.addWidget(self.fontCombo, 1)
+ controlsLayout.addWidget(sizeLabel)
+ controlsLayout.addWidget(self.sizeCombo, 1)
+ controlsLayout.addWidget(styleLabel)
+ controlsLayout.addWidget(self.styleCombo, 1)
+ controlsLayout.addWidget(fontMergingLabel)
+ controlsLayout.addWidget(self.fontMerging, 1)
+ controlsLayout.addStretch(1)
+
+ lineLayout = QHBoxLayout()
+ lineLayout.addWidget(self.lineEdit, 1)
+ lineLayout.addSpacing(12)
+ lineLayout.addWidget(clipboardButton)
+
+ centralLayout = QVBoxLayout()
+ centralLayout.addLayout(controlsLayout)
+ centralLayout.addWidget(self.scrollArea, 1)
+ centralLayout.addSpacing(4)
+ centralLayout.addLayout(lineLayout)
+ centralWidget.setLayout(centralLayout)
+
+ self.setCentralWidget(centralWidget)
+ self.setWindowTitle("Character Map")
+
+ def findStyles(self, font):
+ fontDatabase = QFontDatabase()
+ currentItem = self.styleCombo.currentText()
+ self.styleCombo.clear()
+
+ for style in fontDatabase.styles(font.family()):
+ self.styleCombo.addItem(style)
+
+ styleIndex = self.styleCombo.findText(currentItem)
+ if styleIndex == -1:
+ self.styleCombo.setCurrentIndex(0)
+ else:
+ self.styleCombo.setCurrentIndex(styleIndex)
+
+ def findSizes(self, font):
+ fontDatabase = QFontDatabase()
+ currentSize = self.sizeCombo.currentText()
+ self.sizeCombo.blockSignals(True)
+ self.sizeCombo.clear()
+
+ if fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font)):
+ for size in QFontDatabase.standardSizes():
+ self.sizeCombo.addItem(str(size))
+ self.sizeCombo.setEditable(True)
+ else:
+ for size in fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font)):
+ self.sizeCombo.addItem(str(size))
+ self.sizeCombo.setEditable(False)
+
+ self.sizeCombo.blockSignals(False)
+
+ sizeIndex = self.sizeCombo.findText(currentSize)
+ if sizeIndex == -1:
+ self.sizeCombo.setCurrentIndex(max(0, self.sizeCombo.count() / 3))
+ else:
+ self.sizeCombo.setCurrentIndex(sizeIndex)
+
+ def insertCharacter(self, character):
+ self.lineEdit.insert(character)
+
+ def updateClipboard(self):
+ self.clipboard.setText(self.lineEdit.text(), QClipboard.Clipboard)
+ self.clipboard.setText(self.lineEdit.text(), QClipboard.Selection)
+
+
+if __name__ == '__main__':
+
+ import sys
+
+ representationFactories.registerAllFactories()
+ app = QApplication(sys.argv)
+ window = MainWindow(Font("C:\\Veloce.ufo"))
+ window.show()
+ sys.exit(app.exec_())