Ejemplo n.º 1
0
    def updateDisplay(self, tweak, slotIndex = 0, highlight = False) :
        if not self.updateable :
            # In the middle of a mouse move - don't regenerate (ie, delete) anything.
            return
            
        jsonResult = self.app.runGraphiteOverString(self.app.fontFileName, None, tweak.text, 10, #self.font.size,
            tweak.rtl, tweak.feats, tweak.lang, tweak.width)
        
        if jsonResult != False :
            self.json = jsonResult
        else :
            print "No Graphite result"
            self.json = None

        self.run = Run(tweak.rtl)
        if self.json :
            self.run.addSlots(self.json[-1]['output'])
        self.runView.loadRun(self.run, self.font, resize = False)
        if not self.runloaded :
            try :
                # Don't switch to the Slot tab, but just update the contents.
                self.runView.slotSelected.connect(self.app.tab_slot.changeData)
                self.runView.glyphSelected.connect(self.app.glyphAttrib.changeData)
                self.runloaded = True
            except :
                print "Selection connection failed"

        # Bring the Tweak tab to the front
        self.app.tab_results.setCurrentWidget(self.app.tab_tweakview)
        
        if highlight :
            self.highlightSlot(slotIndex)
Ejemplo n.º 2
0
    def initializeLayout(self, xmlFile):
        vsplitter = QtGui.QSplitter()  # allows sizing of results view
        vsplitter.setOrientation(QtCore.Qt.Vertical)
        vsplitter.setContentsMargins(0, 0, 0, 0)
        vsplitter.setHandleWidth(4)
        self.layout.addWidget(vsplitter)

        self.widget = QtGui.QWidget(vsplitter)
        vbox = QtGui.QVBoxLayout(self.widget)  # MatchList + input control
        vbox.setContentsMargins(*Layout.buttonMargins)
        vbox.setSpacing(Layout.buttonSpacing)

        hbox = QtGui.QHBoxLayout(
        )  # just in case we want to add more buttons here
        vbox.addLayout(hbox)
        plabel = QtGui.QLabel("Search pattern:")
        hbox.addWidget(plabel)
        hbox.addStretch()
        hbox.setContentsMargins(*Layout.buttonMargins)
        hbox.setSpacing(Layout.buttonSpacing)
        searchGo = QtGui.QToolButton(self.widget)
        searchGo.setDefaultAction(self.aSearchGo)
        hbox.addWidget(searchGo)

        self.patternEdit = TextEditReturn(self.widget, self)
        self.patternEdit.setMaximumHeight(Layout.runEditHeight)
        vbox.addWidget(self.patternEdit)
        vbox.addSpacing(5)

        self.matchList = MatchList(self.app, self.font, xmlFile, self)
        #self.matchList.itemClicked.connect(self.itemClicked)
        vbox.addWidget(self.matchList)

        # line below MatchList
        line = QtGui.QFrame(self.widget)
        line.setFrameStyle(QtGui.QFrame.HLine | QtGui.QFrame.Raised)
        line.setLineWidth(2)
        vbox.addWidget(line)
        vbox.addSpacing(2)

        # input control
        self.runEdit = QtGui.QPlainTextEdit(self.widget)
        self.runEdit.setMaximumHeight(Layout.runEditHeight)
        vbox.addWidget(self.runEdit)

        # control buttons
        hbox = QtGui.QHBoxLayout()
        vbox.addLayout(hbox)
        hbox.setContentsMargins(*Layout.buttonMargins)
        hbox.setSpacing(Layout.buttonSpacing)
        runGo = QtGui.QToolButton(self.widget)
        runGo.setDefaultAction(self.aRunGo)
        hbox.addWidget(runGo)
        hbox.addStretch()
        self.runRtl = QtGui.QCheckBox("RTL", self.widget)
        self.runRtl.setChecked(True if configintval(self.app.config, 'main',
                                                    'defaultrtl') else False)
        self.runRtl.setToolTip("Process text right to left")
        hbox.addWidget(self.runRtl)
        self.runFeats = QtGui.QToolButton(self.widget)
        #self.runFeats.setDefaultAction(self.aRunFeats)
        hbox.addWidget(self.runFeats)
        #runAdd = QtGui.QToolButton(self.widget)
        #runAdd.setDefaultAction(self.aRunAdd)
        #hbox.addWidget(runAdd)

        # test output
        self.run = Run(self.font, self.runRtl.isChecked())
        self.runView = RunView(self.font)
        self.runView.gview.resize(self.runView.gview.width(),
                                  self.font.pixrect.height() + 5)
        vsplitter.addWidget(self.runView.gview)
Ejemplo n.º 3
0
class TweakView(QtGui.QWidget) :
    
    # tweaker => Tweaker

    # Communication with the Glyph and Slot tabs
    slotSelected = QtCore.Signal(DataObj, ModelSuper)
    glyphSelected = QtCore.Signal(DataObj, ModelSuper)


    @QtCore.Slot(DataObj, ModelSuper)
    def changeSlot(self, data, model) :
        self.slotSelected.emit(data, model)
        #self.tweaker.changeSlot(...)


    @QtCore.Slot(DataObj, ModelSuper)
    def changeGlyph(self, data, model) :
        self.glyphSelected.emit(data, model)
        if self.currsel and self.currsel != model :
            self.currsel.clearSelected()
        self.currsel = model


    def __init__(self, fontname, size, app = None, parent = None) :
        super(TweakView, self).__init__(parent)
        
        self.app = app
        self.runloaded = False
        self.tweaker = None # set later
        
        self.fontname = fontname
        self.setFont(size)

        if self.fontname and self.fontname != "":
            self._createRunView()
        
        self.currSlotIndex = -1
        self.updateable = True
        
    def _createRunView(self) :
        layout = QtGui.QVBoxLayout(self)
        self.runView = TweakableRunView(self.font, run = None, parent = self)
        self.runView.gview.resize(self.runView.gview.width(), (self.font.pixrect.height() + 5))
        layout.addWidget(self.runView.gview)
        # Ignore runView.tview - text view that shows the glyph names.
        
        
    def updateFromConfigSettings(self, fontname, config) :
        self.fontname = fontname
        self.setFont(configintval(config, 'ui', 'tweakglyphsize'))
        self._createRunView()
        

    def changeFontSize(self, size) :
        self.setFont(size)
        

    def setFont(self, size) :
        if self.fontname and self.fontname != "":
            fontfile = str(self.fontname)
            self.font = GraideFont()
            self.font.loadFont(fontfile, size)
            self.font.loadEmptyGlyphs()
        

    def setTweaker(self, tweaker) :
        # The Tweaker has all the data in it, which is needed to display the glyphs at their
        # adjusted offsets.
        self.tweaker = tweaker
        

    def setUpdateable(self, state) :
        self.updateable = state
        

    def updateDisplay(self, tweak, slotIndex = 0, highlight = False) :
        if not self.updateable :
            # In the middle of a mouse move - don't regenerate (ie, delete) anything.
            return
            
        jsonResult = self.app.runGraphiteOverString(self.app.fontFileName, None, tweak.text, 10, #self.font.size,
            tweak.rtl, tweak.feats, tweak.lang, tweak.width)
        
        if jsonResult != False :
            self.json = jsonResult
        else :
            print "No Graphite result"
            self.json = None

        self.run = Run(tweak.rtl)
        if self.json :
            self.run.addSlots(self.json[-1]['output'])
        self.runView.loadRun(self.run, self.font, resize = False)
        if not self.runloaded :
            try :
                # Don't switch to the Slot tab, but just update the contents.
                self.runView.slotSelected.connect(self.app.tab_slot.changeData)
                self.runView.glyphSelected.connect(self.app.glyphAttrib.changeData)
                self.runloaded = True
            except :
                print "Selection connection failed"

        # Bring the Tweak tab to the front
        self.app.tab_results.setCurrentWidget(self.app.tab_tweakview)
        
        if highlight :
            self.highlightSlot(slotIndex)
        # otherwise done in Tweaker::tweakChanged
    
    # end of updateDisplay
    
    
    def highlightSlot(self, slotIndex) :
        self.currSlotIndex = slotIndex
        self.runView.glyphClicked(None, slotIndex, False)


#    def snagKeyPress(self, event) :
#        self.runView.keyPressEvent(event)
#        self.runView.snagFocus()

#end of class TweakView
Ejemplo n.º 4
0
    def loadResults(self, font, jsonall, gdx = None, rtl = False, fontIsRtl = False) :
        self.rulesJson = []
        self.collFixJson = []
        self.selectRow(-1)
        self.currsel = None
        if jsonall :
            json = jsonall[-1]
            ###json = jsonall[0]
        else :
            json = {'passes' : [], 'output' : [] }  # empty output
        num = len(json['passes']) + 1  # 0 = Init
        count = num
        
        runDir = "rtl" if rtl else "ltr"
        fontDir = "rtl" if fontIsRtl else "ltr"
        
        # JSON format:
        #   'passes': [
        #      0:
        #        'id' : 1
        #        'rundir' : 'ltr'
        #        'slotsdir' : 'rtl'
        #        'slots' : <initial data>
        #        'rules' : <rules run by pass 1>
        #      1:
        #        'id' : 2
        #        'rundir' : 'ltr'
        #        'slotsdir' : 'rtl'
        #        'slots' : <output of pass 1>
        #        'rules' : <rules run by pass 2>
        #      ...
        #      N-1:
        #        'id' : N
        #        'slots' : <output of pass N-1>
        #        'rules' : <rules run by pass N>
        #   ]
        #   'outputdir' : 'rtl'
        #   'output': <output of pass N>
        
        # Also note that pass IDs in JSON do not match pass indices in GDX when there is
        # a bidi pass. In JSON, the pass ID of a bidi pass in json is -1, with the
        # first positioning pass index = last subs pass + 1. (More accurately, -1 indicates
        # the INPUT to the bidi pass.) In GDX, pass indices include the bidi pass, so first
        # positioning pass index = last subs pass + 2.
        #
        # Best thing to do is to more or less ignore the JSON pass IDs, since they are not reliable.
            
        if count != self.rowCount() :
            if count < self.rowCount() : self.runViews = self.runViews[:count]
            self.setRowCount(count)
        w = 0
        wt = 0
        for j in range(num) :
            # Process the output of pass J which = input to pass J+1;  the rules are listed with pass J-1.
            # Note for J = 0 there are no rules.
            run = Run(font, rtl)
            highlight = False
            if j < num - 1 :
                run.addSlots(json['passes'][j]['slots'])  # output of pass J
                #passid = int(json['passes'][j]['id']) - 1
            else :
                run.addSlots(json['output'])   # final output
                #passid = j
            
            #print "*** in loadResults: pass",j,"***"
            #run.printDebug()
            
            if j == 0 :
                pname = "Init"
                if runDir != fontDir :
                    pname += " (LTR) " if fontIsRtl else " (RTL) "  # direction reversed
                self.rulesJson.append(None)
                self.collFixJson.append(None)
                self.dirLabels.append("")
                self.flipFlags.append(False)
                
            else :
                pname = "Pass: %d" % j

                if j < num - 1 :
                    slotDir = json['passes'][j]['slotsdir']
                    passDir = json['passes'][j-1]['passdir']  # where the rules come from
                else : 
                    slotDir = json['outputdir']
                    passDir = json['passes'][j-1]['passdir']  # where the rules come from 
                #print j,"- slot dir=",slotDir, "; pass dir=",passDir
                if slotDir != passDir :
                    run.reverseDirection()
                    #run.printDebug()
                
                flipFlag = False
                dirLabel = ""
                if gdx :
                    pname += " - " + gdx.passTypes[j-1]  # j-1 because Init is not in the passTypes array
                    if passDir != fontDir :
                        dirLabel = " (LTR)" if passDir == "ltr" else " (RTL)"  # direction reversed
                        pname += dirLabel + " "
                        flipFlag = True
                        
                self.flipFlags.append(flipFlag)
                self.dirLabels.append(dirLabel)
                    
                if json['passes'][j-1].has_key('rules') and len(json['passes'][j-1]['rules']) :
                    highlight = "active"
                    self.rulesJson.append(json['passes'][j-1]['rules'])  # rules are stored with previous pass :-(
                else :
                    self.rulesJson.append(None)
                
                # Add rows for any collisions, if this is such a pass.
                if 1 < j and j < num and gdx and gdx.passTypes[j-1] == "positioning":
                    thisSlots = json['output'] if (j == num - 1) else json['passes'][j]['slots']
                    if self.hasCollisionFixedSlot(json['passes'][j-1]['slots'], thisSlots) :
                        highlight = "semi-active"
                if json['passes'][j-1].has_key('collisions') :
                    self.collFixJson.append(json['passes'][j-1]['collisions'])
                else :
                    self.collFixJson.append(None)
                    
                # if passid == -1, NEXT pass is bidi pass
                    
            (neww, newt) = self.addRun(font, run, pname, j, highlight = highlight)
            w = max(w, neww)
            wt = max(wt, newt)
            
        self.finishLoad(w, wt)  # set column widths, etc