Exemplo n.º 1
0
class TRGlyphInfo(QtGui.QVBoxLayout):
    # - Split/Break contour
    def __init__(self):
        super(TRGlyphInfo, self).__init__()

        # -- Init
        self.table_dict = {0: {0: None}}  # Empty table

        # -- Widgets
        self.lay_head = QtGui.QGridLayout()

        self.edt_glyphName = QtGui.QLineEdit()
        self.edt_glyphsSeq = QtGui.QLineEdit()
        self.edt_glyphName.setToolTip('Current Glyph Name.')
        self.edt_glyphsSeq.setToolTip(
            'Manual entry for Glyph names to populate stats info. Separated by SPACE'
        )

        self.cmb_query = QtGui.QComboBox()
        self.cmb_charset = QtGui.QComboBox()
        self.cmb_query.setToolTip('Select query type.')
        self.cmb_charset.setToolTip('Select character set to compare with.')

        # --- Add queries
        self.query_list = [
            '(BBox) Bounding Box Width', '(BBox) Bounding Box Height',
            '(Metrics) Advance Width', '(Metrics) Left Side-bearing',
            '(Metrics) Right Side-bearing'
        ]

        self.cmb_query.addItems(self.query_list)

        self.btn_refresh = QtGui.QPushButton('&Refresh')
        self.btn_populate = QtGui.QPushButton('&Populate')
        self.btn_get = QtGui.QPushButton('&Window')
        self.btn_probe = QtGui.QPushButton('Glyph')
        self.btn_units = QtGui.QPushButton('Percent')

        self.btn_refresh.setToolTip('Refresh active glyph and table.')
        self.btn_populate.setToolTip(
            'Populate character set selector from current font.')
        self.btn_get.setToolTip('Get current string from active Glyph Window.')
        self.btn_probe.setToolTip(
            'Toggle between Row (Glyph) or Column (Layer) based comparison.')
        self.btn_units.setToolTip(
            'Toggle the results beeing shown as (Units) or (Percent).')

        self.btn_probe.setCheckable(True)
        self.btn_units.setCheckable(True)
        self.btn_probe.setChecked(False)
        self.btn_units.setChecked(False)

        # !!! Disable for now
        self.cmb_charset.setEnabled(False)
        self.btn_populate.setEnabled(False)

        # -- Build Layout
        self.lay_head.addWidget(QtGui.QLabel('G:'), 0, 0, 1, 1)
        self.lay_head.addWidget(self.edt_glyphName, 0, 1, 1, 5)
        self.lay_head.addWidget(self.btn_refresh, 0, 6, 1, 2)
        #self.lay_head.addWidget(QtGui.QLabel('C:'),	1,0,1,1)
        #self.lay_head.addWidget(self.cmb_charset,	1,1,1,5)
        #self.lay_head.addWidget(self.btn_populate,	1,6,1,2)
        self.lay_head.addWidget(QtGui.QLabel('C:'), 2, 0, 1, 1)
        self.lay_head.addWidget(self.edt_glyphsSeq, 2, 1, 1, 5)
        self.lay_head.addWidget(self.btn_get, 2, 6, 1, 2)
        self.lay_head.addWidget(QtGui.QLabel('Q:'), 3, 0, 1, 1)
        self.lay_head.addWidget(self.cmb_query, 3, 1, 1, 5)
        self.lay_head.addWidget(self.btn_probe, 3, 6, 1, 2)
        self.addLayout(self.lay_head)

        # -- Table
        self.tab_stats = TRTableView(self.table_dict)
        #self.refresh()

        # -- Note/Descriotion
        self.addWidget(self.tab_stats)
        self.addWidget(self.btn_units)

        # -- Addons
        self.btn_refresh.clicked.connect(self.refresh)
        self.btn_populate.clicked.connect(self.populate)
        self.btn_get.clicked.connect(self.get_string)
        self.btn_probe.clicked.connect(self.toggle_query)
        self.btn_units.clicked.connect(self.toggle_units)
        self.cmb_query.currentIndexChanged.connect(self.refresh)

        # -- Table Styling
        self.tab_stats.horizontalHeader().setStretchLastSection(False)
        self.tab_stats.resizeColumnsToContents()
        self.tab_stats.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self.tab_stats.selectionModel().selectionChanged.connect(
            self.change_selection)

    def populate(self):
        font = pFont()
        self.glyphNames = font.getGlyphNamesDict()
        self.cmb_charset.addItems(sorted(self.glyphNames.keys()))

    def get_string(self):
        workspace = pWorkspace()
        glyphsSeq = ' '.join(
            sorted(
                list(
                    set([
                        glyph.name for glyph in workspace.getTextBlockGlyphs()
                    ]))))
        self.edt_glyphsSeq.setText(glyphsSeq)

    def refresh(self, layer=None):
        # - Init
        font = pFont()
        glyph = eGlyph()
        pLayers = (
            True, True, False, False
        )  # !!! Quickfix: Stats crashes FL after mode switch + refresh
        wLayers = glyph._prepareLayers(pLayers)
        self.table_data, self.table_proc = {}, {}

        current_glyph_name = eGlyph().name
        self.edt_glyphName.setText(current_glyph_name)

        # - Populate table
        process_glyph_names = [current_glyph_name
                               ] + self.edt_glyphsSeq.text.split(' ') if len(
                                   self.edt_glyphsSeq.text) else [
                                       current_glyph_name
                                   ]

        for glyph_name in process_glyph_names:
            wGlyph = font.glyph(glyph_name)
            self.table_data[glyph_name] = {
                layer: self.process_query(wGlyph, layer,
                                          self.cmb_query.currentText)
                for layer in wLayers
            }

        self.tab_stats.setTable(self.table_data)
        self.tab_stats.resizeColumnsToContents()

    def change_selection(self):
        # - Helper for avoiding ZeroDivision error
        def noZero(value):
            return value if value != 0 else 1

        # - Init
        base_index = self.tab_stats.selectionModel().selectedIndexes[0]
        base_name = self.tab_stats.verticalHeaderItem(base_index.row()).text()
        base_layer = self.tab_stats.horizontalHeaderItem(
            base_index.column()).text()

        for glyph_name, glyph_layers in self.table_data.iteritems():
            if not self.btn_probe.isChecked():
                if self.btn_units.isChecked():
                    self.table_proc[glyph_name] = {
                        layer_name: -round(
                            self.table_data[base_name][layer_name] -
                            layer_value, 2)
                        for layer_name, layer_value in
                        glyph_layers.iteritems()
                    }
                else:
                    self.table_proc[glyph_name] = {
                        layer_name: '%s %%' % round(
                            ratfrac(
                                noZero(layer_value),
                                noZero(
                                    self.table_data[base_name][layer_name])),
                            2)
                        for layer_name, layer_value in
                        glyph_layers.iteritems()
                    }
            else:
                if self.btn_units.isChecked():
                    self.table_proc[glyph_name] = {
                        layer_name: -round(
                            self.table_data[glyph_name][base_layer] -
                            layer_value, 2)
                        for layer_name, layer_value in
                        glyph_layers.iteritems()
                    }
                else:
                    self.table_proc[glyph_name] = {
                        layer_name: '%s %%' % round(
                            ratfrac(
                                noZero(layer_value),
                                noZero(
                                    self.table_data[glyph_name][base_layer])),
                            2)
                        for layer_name, layer_value in
                        glyph_layers.iteritems()
                    }

        self.tab_stats.setTable(self.table_proc)
        self.tab_stats.resizeColumnsToContents()

    def toggle_query(self):
        if self.btn_probe.isChecked():
            self.btn_probe.setText('Layer')
            self.tab_stats.setSelectionBehavior(
                QtGui.QAbstractItemView.SelectColumns)
        else:
            self.btn_probe.setText('Glyph')
            self.tab_stats.setSelectionBehavior(
                QtGui.QAbstractItemView.SelectRows)

    def toggle_units(self):
        if self.btn_units.isChecked():
            self.btn_units.setText('Units')
        else:
            self.btn_units.setText('Percent')

    def process_query(self, glyph, layer, query):
        if 'bbox' in query.lower() and 'width' in query.lower():
            return glyph.getBounds(layer).width()
        if 'bbox' in query.lower() and 'height' in query.lower():
            return glyph.getBounds(layer).height()
        if 'metrics' in query.lower() and 'advance' in query.lower():
            return glyph.getAdvance(layer)
        if 'metrics' in query.lower() and 'left' in query.lower():
            return glyph.getLSB(layer)
        if 'metrics' in query.lower() and 'right' in query.lower():
            return glyph.getRSB(layer)
Exemplo n.º 2
0
class TRContourSelect(QtGui.QVBoxLayout):
    # - Split/Break contour
    def __init__(self):
        super(TRContourSelect, self).__init__()

        # -- Init
        self.table_dict = {0: {0: None}}  # Empty table
        self.layer_names = []  # Empty layer list
        #self.table_columns = 'N,Shape,Contour,X,Y,Type,Relative'.split(',')
        self.table_columns = 'N,Sh,Cn,X,Y,Type,Rel'.split(',')

        # -- Widgets
        self.lay_head = QtGui.QGridLayout()

        self.edt_glyphName = QtGui.QLineEdit()
        self.cmb_layer = QtGui.QComboBox()

        self.btn_refresh = QtGui.QPushButton('&Refresh')
        self.btn_apply = QtGui.QPushButton('&Apply')
        self.btn_apply.setEnabled(False)

        # -- Build Layout
        self.lay_head.addWidget(QtGui.QLabel('G:'), 0, 0, 1, 1)
        self.lay_head.addWidget(self.edt_glyphName, 0, 1, 1, 5)
        self.lay_head.addWidget(self.btn_refresh, 0, 6, 1, 2)
        self.lay_head.addWidget(QtGui.QLabel('L:'), 1, 0, 1, 1)
        self.lay_head.addWidget(self.cmb_layer, 1, 1, 1, 5)
        self.lay_head.addWidget(self.btn_apply, 1, 6, 1, 2)
        self.addLayout(self.lay_head)

        # -- Node List Table
        self.tab_nodes = TRTableView(self.table_dict)

        self.addWidget(self.tab_nodes)
        #self.refresh() # Build Table

        self.btn_refresh.clicked.connect(lambda: self.refresh())
        self.cmb_layer.currentIndexChanged.connect(lambda: self.changeLayer())

        # -- Table Styling
        self.tab_nodes.horizontalHeader().setStretchLastSection(False)
        self.tab_nodes.setSortingEnabled(True)
        self.tab_nodes.horizontalHeader().sortIndicatorChanged.connect(
            lambda: self.tab_nodes.resizeColumnsToContents())
        self.tab_nodes.verticalHeader().hide()
        self.tab_nodes.resizeColumnsToContents()
        self.tab_nodes.selectionModel().selectionChanged.connect(
            self.selectionChanged)
        self.tab_nodes.itemChanged.connect(self.valueChanged)

    def refresh(self, layer=None):
        # - Init
        self.glyph = eGlyph()
        self.edt_glyphName.setText(eGlyph().name)

        self.table_dict = {}
        node_count = 0

        # - Populate layers
        if layer is None:
            self.layer_names = [
                item.name for item in self.glyph.layers()
                if '#' not in item.name
            ]
            self.cmb_layer.clear()
            self.cmb_layer.addItems(self.layer_names)
            self.cmb_layer.setCurrentIndex(
                self.layer_names.index(self.glyph.activeLayer().name))

        # - Populate table
        try:  # Dirty Quick Fix - Solve later
            for sID, shape in enumerate(self.glyph.shapes(layer)):
                for cID, contour in enumerate(shape.contours):
                    for nID, node in enumerate(contour.nodes()):

                        table_values = [
                            node_count, sID, cID,
                            round(node.x, 2),
                            round(node.y, 2), node.type,
                            round(eNode(node).distanceToPrev(), 2)
                        ]

                        self.table_dict[node_count] = OrderedDict(
                            zip(self.table_columns, table_values))
                        node_count += 1

            self.tab_nodes.setTable(self.table_dict, (False, False))
            self.tab_nodes.resizeColumnsToContents()

        except AttributeError:
            pass

    def doCheck(self):
        if self.glyph.fg.id != fl6.CurrentGlyph(
        ).id and self.glyph.fl.name != fl6.CurrentGlyph().name:
            print '\nERRO:\tGlyph mismatch:\n\tCurrent active glyph: %s\n\tOutline panel glyph: %s' % (
                fl6.CurrentGlyph(), self.glyph.fg)
            print 'WARN:\tNo action taken! Forcing refresh!'
            self.refresh()
            return 0
        return 1

    def changeLayer(self):
        if self.doCheck():
            self.refresh(self.cmb_layer.currentText)

    def selectionChanged(self):
        if self.doCheck():
            if self.cmb_layer.currentText == self.glyph.activeLayer().name:
                # - Prepare
                self.glyph.fl.unselectAllNodes()

                # - Process
                for cel_coords in self.tab_nodes.selectionModel(
                ).selectedIndexes:
                    #print self.tab_nodes.item(cel_coords.row(), cel_coords.column()).text()
                    selected_nid = int(
                        self.tab_nodes.item(cel_coords.row(), 0).text())
                    self.glyph.nodes(self.cmb_layer.currentText
                                     )[selected_nid].selected = True

                # - Finish
                self.glyph.updateObject(self.glyph.fl, verbose=False)

    def valueChanged(self, item):
        if self.doCheck():
            #print item.text(), item.row()
            try:  # Dirty Quick Fix - Solve later
                # - Init
                x_col, y_col = self.table_columns.index(
                    'X'), self.table_columns.index('Y')
                active_nid = int(self.tab_nodes.item(item.row(), 0).text())

                # - Process
                if item.column() == x_col or item.column() == y_col:
                    new_x = float(
                        self.tab_nodes.item(item.row(), x_col).text())
                    new_y = float(
                        self.tab_nodes.item(item.row(), y_col).text())

                    active_node = eNode(
                        self.glyph.nodes(
                            self.cmb_layer.currentText)[active_nid])
                    active_node.reloc(new_x, new_y)

                    # -- Finish
                    self.glyph.update()
                    self.glyph.updateObject(self.glyph.fl, verbose=False)

            except AttributeError:
                pass