Example #1
0
def reverseContours(glyph):
    glyphCopy = RGlyph()
    glyphCopy.width = glyph.width
    pointPen = glyphCopy.getPointPen()
    reversePen = ReverseContourPointPen(pointPen)
    glyph.drawPoints(reversePen)
    return glyphCopy
Example #2
0
def reverseContours(glyph):
    glyphCopy = RGlyph()
    glyphCopy.width = glyph.width
    pointPen = glyphCopy.getPointPen()
    reversePen = ReverseContourPointPen(pointPen)
    glyph.drawPoints(reversePen)
    return glyphCopy
Example #3
0
def removeOverlap(glyph):
    glyphCopy = RGlyph()
    glyphCopy.width = glyph.width
    pointPen = glyphCopy.getPointPen()
    glyph.drawPoints(pointPen)
    glyphCopy.removeOverlap()
    return glyphCopy
Example #4
0
 def getCleanedGlyph(self, glyph):
     cleanGlyph = RGlyph()
     cleanGlyph.width = glyph.width
     pen = cleanGlyph.getPointPen()
     cleanPen = FilterPointPen()
     glyph.drawPoints(cleanPen)
     cleanPen.extract(pen)
     return cleanGlyph
Example #5
0
 def getCleanedGlyph(self, glyph):
     cleanGlyph = RGlyph()
     cleanGlyph.width = glyph.width
     pen = cleanGlyph.getPointPen()
     cleanPen = FilterPointPen()
     glyph.drawPoints(cleanPen)
     cleanPen.extract(pen)
     return cleanGlyph
Example #6
0
def copyContours(glyph):
    glyphCopy = RGlyph()
    glyphCopy.width = glyph.width
    pen = glyphCopy.getPen()
    glyph.draw(pen)
    glyphCopy.unicode = glyph.unicode
    glyphCopy.name = glyph.name
    return glyphCopy
Example #7
0
def extractComposites(glyph):
    """Return a new glyph with outline copies of each composite from the source glyph."""

    decomposedComposites = RGlyph()

    if len(glyph.components):
        font = glyph.getParent()

        for comp in reversed(glyph.components):

            # obtain source data
            baseGlyphName = comp.baseGlyph
            baseGlyph = font[baseGlyphName]
            t = transform.Transform(*comp.transformation)

            # create a temporary glyph on which to draw the decomposed composite
            single_decomposedComposite = RGlyph()
            decompPen = single_decomposedComposite.getPen()
            baseGlyph.draw(decompPen)
            single_decomposedComposite.transform(t)

            # add single composite to the returned glyph
            decomposedComposites.appendGlyph(single_decomposedComposite)

    return decomposedComposites
Example #8
0
File: RF.py Project: yanone/ynlib
def RGlyphFromGlifString(glifString):
	"""\
	Return RGlyph object directly from .glif file
	"""
	
	from robofab.world import RGlyph
	from robofab.glifLib import readGlyphFromString
	
	glyph = RGlyph()
	readGlyphFromString(glifString, glyph, glyph.getPointPen())
	return glyph
Example #9
0
 def _getInstanceGlyph(self, location, masters):
     I = self._getInstance(location, masters)
     if I is not None:
         return I.extractGlyph(RGlyph())
     else:
         errorMessage = self.mutatorErrors[-1]['error']
         return ErrorGlyph('Interpolation', errorMessage)
Example #10
0
 def test_extract_scaled_glyph_as_Robofab_Glyph(self):
     """Test scaled glyph retrieval as a Robofab Glyph."""
     from robofab.world import RGlyph
     for testFont in [self.smallFont, self.stemedSmallFont]:
         scaledGlyph = RGlyph()
         for glyphName in self.glyphNames:
             testFont.extractGlyph(glyphName, scaledGlyph)
             self.assertIsInstance(scaledGlyph, RGlyph)
    def normalizeGlyph(self, glyph):
        componentsCollector = CollectComponentsPen()
        glyph.draw(componentsCollector)
        components = componentsCollector.get()
        anchors = []

        for anchor in reversed(glyph.anchors):
            anchors.append((anchor.name, (anchor.x, anchor.y)))

        cleanGlyph = RGlyph()
        cleanGlyph.width = glyph.width
        pen = cleanGlyph.getPointPen()
        cleanPen = FilterPointPen()
        glyph.drawPoints(cleanPen)
        cleanPen.extract(pen)

        return cleanGlyph, components, anchors
Example #12
0
    def normalizeGlyph(self, glyph):
        componentsCollector = CollectComponentsPen()
        glyph.draw(componentsCollector)
        components = componentsCollector.get()
        anchors = []

        for anchor in reversed(glyph.anchors):
            anchors.append((anchor.name, (anchor.x, anchor.y)))

        cleanGlyph = RGlyph()
        cleanGlyph.width = glyph.width
        pen = cleanGlyph.getPointPen()
        cleanPen = FilterPointPen()
        glyph.drawPoints(cleanPen)
        cleanPen.extract(pen)

        return cleanGlyph, components, anchors
Example #13
0
def extractComposites(glyph):
    """Return a new glyph with outline copies of each composite from the source glyph."""

    decomposedComposites = RGlyph()

    if len(glyph.components):
        font = glyph.getParent()

        for comp in reversed(glyph.components):

            # obtain source data
            baseGlyphName = comp.baseGlyph
            baseGlyph = font[baseGlyphName]
            t = transform.Transform(*comp.transformation)

            # create a temporary glyph on which to draw the decomposed composite
            single_decomposedComposite = RGlyph()
            decompPen = single_decomposedComposite.getPen()
            baseGlyph.draw(decompPen)
            single_decomposedComposite.transform(t)

            # add single composite to the returned glyph
            decomposedComposites.appendGlyph(single_decomposedComposite)

    return decomposedComposites
Example #14
0
def removeOverlap(glyph):
    glyphCopy = RGlyph()
    glyphCopy.width = glyph.width
    pointPen = glyphCopy.getPointPen()
    glyph.drawPoints(pointPen)
    glyphCopy.removeOverlap()
    return glyphCopy
Example #15
0
def removeOverlap(glyph):

    toRFGlyph = RGlyph()
    toRFpen = toRFGlyph.getPen()
    glyph.draw(toRFpen)

    singleContourGlyph = RGlyph()
    singleContourGlyph.width = glyph.width
    singleContourGlyph.name = glyph.name
    pointPen = singleContourGlyph.getPointPen()

    if len(toRFGlyph) > 1:

        booleanGlyphs = []

        for c in toRFGlyph.contours:
            if len(c) > 1:
                b = BooleanGlyph()
                pen = b.getPen()
                c.draw(pen)
                booleanGlyphs.append(b)

        finalBooleanGlyph = reduce(lambda g1, g2: g1 | g2, booleanGlyphs)
        finalBooleanGlyph.drawPoints(pointPen)

    else:
        glyph.drawPoints(pointPen)

    return singleContourGlyph
Example #16
0
def copyContours(glyph):
    glyphCopy = RGlyph()
    glyphCopy.width = glyph.width
    pen = glyphCopy.getPen()
    glyph.draw(pen)
    glyphCopy.unicode = glyph.unicode
    glyphCopy.name = glyph.name
    return glyphCopy
Example #17
0
def freezeGlyph(glyph):
    """Return a copy of a glyph, with components decomposed and all overlap removed."""

    toRFGlyph = RGlyph()
    toRFpen = toRFGlyph.getPen()
    glyph.draw(toRFpen)

    if len(glyph.components):
        decomposedComponents = extractComposites(glyph)
        decomposedComponents.draw(toRFpen)

    singleContourGlyph = RGlyph()
    singleContourGlyph.width = glyph.width
    singleContourGlyph.name = glyph.name
    pointPen = singleContourGlyph.getPointPen()

    if len(toRFGlyph.contours) > 1:

        try:
            booleanGlyphs = []

            for c in toRFGlyph.contours:
                if len(c) > 1:
                    b = BooleanGlyph()
                    pen = b.getPen()
                    c.draw(pen)
                    booleanGlyphs.append(b)

            finalBooleanGlyph = reduce(lambda g1, g2: g1 | g2, booleanGlyphs)
            finalBooleanGlyph.drawPoints(pointPen)

        except:
            toRFGlyph.drawPoints(pointPen)
    else:
        toRFGlyph.drawPoints(pointPen)

    return singleContourGlyph
    def __call__(self, glyph, font, **arguments):
        try:
            filteredGlyph = RGlyph()
            filteredGlyph.width = glyph.width
            drawingPen = filteredGlyph.getPen()
            filterPen = self.filterObject(drawingPen, **arguments)
            glyph.draw(filterPen)
        except:
            try:
                sourceGlyph = RGlyph()
                sourceGlyph.appendGlyph(glyph)
                sourceGlyph.width = glyph.width
                filteredGlyph = self.filterObject(sourceGlyph, **arguments)
            except:
                filteredGlyph = ErrorGlyph()

        return filteredGlyph
Example #19
0
    def processGlyph(self, glyph, font, **arguments):
        filterObject = self.filterObject
        glyph, components, anchors = self.normalizeGlyph(glyph)

        if inspect.isfunction(filterObject):
            try:
                filteredGlyph = filterObject(glyph, **arguments)
                if filteredGlyph is None:
                    filteredGlyph = glyph

            except Exception as e:
                print u'PenBallWizard — GlyphFilter: Error (function): {0}'.format(
                    e)
                error = True
                filteredGlyph = ErrorGlyph()
        else:
            try:
                filteredGlyph = RGlyph()
                filteredGlyph.width = glyph.width
                drawingPen = filteredGlyph.getPen()
                filterPen = filterObject(drawingPen, **arguments)
                glyph.draw(filterPen)

            except Exception as e:
                print u'PenBallWizard — GlyphFilter: Error (pen): {0}'.format(
                    e)
                error = True
                filteredGlyph = ErrorGlyph()

        for baseGlyphName, transformation in components:
            offset = transformation[-2:]
            scale = (transformation[0], transformation[3])
            filteredGlyph.appendComponent(baseGlyphName, offset, scale)

        for anchor in anchors:
            filteredGlyph.appendAnchor(*anchor)

        return filteredGlyph
        def filterGroup(glyph, font=None, **overrideGlobalArguments):
            globalArguments = {self.splitSubfilterArgumentName(argumentName): self.arguments[argumentName] for argumentName in self.arguments}
            for key in overrideGlobalArguments:
                _subfilterName_, _overrideArgumentName_, _filterOrder_ = self.splitSubfilterArgumentName(key)
                if (_subfilterName_, _overrideArgumentName_) != (None, None):
                    globalArguments[(_subfilterName_, _overrideArgumentName_, _filterOrder_)] = overrideGlobalArguments[key]

            subfilters = [(self.getSubfilter(subfilterName), mode, source) for subfilterName, mode, source in self.subfilters]
            error = False
            canvasGlyph = RGlyph()
            canvasPen = canvasGlyph.getPen()
            canvasGlyph.width = glyph.width
            glyph.draw(canvasPen)

            steps = []

            for i, (currentFilter, mode, source) in enumerate(subfilters):

                if error == True:
                    continue

                if source is None:
                    sourceGlyph = canvasGlyph
                else:
                    try:
                        sourceGlyph = steps[source]
                    except:
                        layerGlyph = glyph.getLayer(source)
                        if len(layerGlyph) > 0:
                            sourceGlyph = RGlyph()
                            pen = sourceGlyph.getPen()
                            layerGlyph.draw(pen)
                        else:
                            sourceGlyph = canvasGlyph

                sourceGlyph.name = glyph.name

                arguments = {argumentName: globalArguments[(subfilterName, argumentName, filterOrder)] for subfilterName, argumentName, filterOrder in globalArguments if subfilterName == currentFilter.name and filterOrder == i}
                processedGlyph = currentFilter.filterGlyph(sourceGlyph, arguments)

                steps.append(processedGlyph)

                if mode in ['union', 'difference', 'intersection', 'xor']:
                    try:
                        b1 = BooleanGlyph(canvasGlyph)
                        b2 = BooleanGlyph(processedGlyph)
                        operation = getattr(b1, mode)
                        processedGlyph = operation(b2)
                    except:
                        error = True

                if mode != 'add':
                    canvasGlyph.clear()

                processedGlyph.draw(canvasPen)

            if error == True:
                canvasGlyph = ErrorGlyph()
            elif error == False:
                canvasGlyph.name = glyph.name

            canvasGlyph.unicode = glyph.unicode
            if canvasGlyph.width is None:
                canvasGlyph.width = glyph.width
            return canvasGlyph
Example #21
0
    def set(self, glyphInput, keepWords=False):
        thisFont = self.thisFont
        kerning = self.kerning
        fontKeys = thisFont.keys()
        if isinstance(glyphInput, str):
            glyphRecord = self.stringToGlyphs(glyphInput)
        elif isinstance(glyphInput, list):
            glyphRecord = glyphInput
            
        suffixes = self.settings['suffix']
        if len(suffixes) > 0:
            for i, glyphName in enumerate(glyphRecord):                  
                for suffix in suffixes:
                    if glyphName + suffix in fontKeys:
                        glyphRecord[i] = glyphName + suffix
            
        kernGroups = self.getKernGroups(glyphRecord)
        nbrOfGlyphs = len(glyphRecord)
        UPM = thisFont.info.unitsPerEm
        descender = thisFont.info.descender
        ascender = thisFont.info.ascender
        capHeight = thisFont.info.capHeight
        xHeight = thisFont.info.xHeight
        
        pointSize = self.type['size']
        _line_Height = self.type['_line_Height'] 
        tracking = self.type['tracking'] 
        color = self.type['color'][0:]
        alpha = self.type['alpha']
        x, y, width, height = self.canvas['posSize']
        
        sc = pointSize/UPM
        xAdvance = yAdvance = 0
        kerningValue = 0
        # exceed allowance: to which extent can a word go beyond bounds
        eA = 0.97
        wordLetterOffset = 0
        spaceWidth = thisFont['space'].width
        glyphGroups = []
        previousGlyph = None
        previousGlyphGroups = []
        wordGlyph = RGlyph()
        wordGlyph.name = ''
        glyphDrawingTime = 0
        wordKerning = []
       
        useKerning = self.settings['useKerning'] 
        showKerning = self.settings['showKerning'] 
        showGlyphBox = self.settings['showGlyphBox'] 
        showFrame = self.settings['showFrame']
        pageStamp = self.settings['pageStamp']

        newPage(*self.formats[self.preset])

        if showFrame: self.showFrame()
        if pageStamp: self.pageStamp()

        # compensate for upward y coordinates
        xPos = x
        yPos = y + height - ((UPM+descender)*sc)
        translate(xPos, yPos)

        for i, glyphName in enumerate(glyphRecord):
            
            # filtering missing glyphs
            if (glyphName not in fontKeys) and (glyphName != '\n'):
                if '.notdef' in fontKeys:
                    glyphName = '.notdef'
                else: continue
          
            # skip spaces at the start of a new line  
            if (glyphName == 'space') and (xAdvance == 0) and (wordLetterOffset == 0):
                continue
            
            if glyphName != '\n':
                glyph = thisFont[glyphName]
            
            # check for need of a new line
            if ((glyphName == '\n') and (not keepWords)) or \
               (xAdvance + (glyph.width*sc*eA) >= width):
                xAdvance = 0
                kerningValue = 0
                yAdvance += (UPM*_line_Height)*sc
                _newLine = False
                previousGlyph = None
                previousGlyphGroups = None
                if (glyphName == '\n'):
                    continue
                    
            # kerning
            if glyphName in kernGroups.keys():
                glyphGroups = kernGroups[glyphName]
                # filter out non kern groups
                glyphGroups = [group for group in glyphGroups if ('MMK' in group) or ('kern' in group)]

                if (previousGlyph is not None) and useKerning:
                    for group in glyphGroups:
                        for prevGroup in previousGlyphGroups:
                            if kerning[(prevGroup,group)] is not None:
                                kerningValue = kerning[(prevGroup,group)]
                
            glyphStart = time()
                
            # if word wrap
            if keepWords:
                # add each glyph of a word to the wordGlyph and skip the drawing
                # add metrics of each glyph to the wordGlyph
                if (glyphName != 'space') and (glyphName != '\n') and (i < nbrOfGlyphs-1):
                    
                    # draw kerning if word wrap
                    if showKerning and (kerningValue != 0):
                        save()
                        scale(sc)
                        fill(1, 0, 0, 0.5)
                        thisKern = BezierPath()
                        thisKern.moveTo((wordLetterOffset, descender))
                        thisKern.lineTo((wordLetterOffset, ascender))
                        thisKern.lineTo((wordLetterOffset + kerningValue, ascender))
                        thisKern.lineTo((wordLetterOffset + kerningValue, descender))
                        thisKern.closePath()
                        wordKerning.append(thisKern)
                        restore()
                    
                    wordGlyph.appendGlyph(glyph, (wordLetterOffset + kerningValue, 0))
                    wordGlyph.width += (glyph.width + tracking + kerningValue)
                    wordGlyph.name += glyphName
                    wordLetterOffset += (glyph.width + tracking + kerningValue)
                    previousGlyph = glyph
                    previousGlyphGroups = glyphGroups
                    kerningValue = 0
                    
                    continue
                    
                # when a space is hit, or if it’s the end of the text
                # the wordglyph is passed as main glyph to be drawn
                # check if the word doesn’t exceed boundaries
                elif (glyphName == 'space') or (glyphName == '\n') or (i == nbrOfGlyphs-1):
                    if (i == nbrOfGlyphs-1) and (glyphName != '\n'):
                        wordGlyph.appendGlyph(glyph, (wordLetterOffset + kerningValue, 0))
                        wordGlyph.width += (glyph.width + tracking)
                        wordGlyph.name += glyphName
                    if glyphName != '\n':
                        previousGlyph = glyph
                        previousGlyphGroups = glyphGroups
                    glyph = wordGlyph
                    wordGlyph = RGlyph()
                    wordGlyph.name = ''
                    wordLetterOffset += tracking + kerningValue
                    if (xAdvance + (glyph.width*sc*eA) >= width):
                        xAdvance = 0  
                        kerningValue = 0
                        yAdvance += (UPM*_line_Height)*sc
                        
            # check for need of a new page   
            if yAdvance + (UPM*sc) >= height:
                newPage()
                if showFrame: self.showFrame()
                if pageStamp: self.pageStamp()
                translate(xPos, yPos)
                xAdvance = 0
                yAdvance = 0
                kerningValue = 0
            
            
            # Drawing, yay!
            save()
            if not keepWords:
                translate(xAdvance + (kerningValue*sc), -yAdvance)
            elif keepWords:
                translate(xAdvance, -yAdvance)
            scale(sc)
            
            # draw kerning if no word wrap
            if showKerning:
                save()
                fill(1, 0, 0, 0.5)
                if not keepWords:
                    if kerningValue > 0:
                        fill(.2, .9, 0, 0.5)
                    rect(0, descender, -kerningValue, UPM)
                elif keepWords:
                    for kern in wordKerning:
                        drawPath(kern)
                wordKerning = []
                restore()
                
            # draw glyphBox
            if showGlyphBox:
                glyphWidth = glyph.width
                save()
                fill()
                stroke(.5)
                rect(0, descender, glyphWidth, UPM)
                for h, c in [(0, (.5,)), (xHeight,(.5, .9, 0)), (capHeight,(.1, .4, .9))]:
                    stroke(*c)
                    line((0, h), (glyphWidth, h))
                restore()
                
            # glyph color    
            if len(color) == 3: 
                fill(*color + (alpha,))
                if alpha < 1: stroke(*color)
            elif len(color) == 4: 
                cmykFill(*color + (alpha,))
                if alpha < 1: cmykStroke(*color)
            else:
                fill(0)
                if alpha < 1:stroke(0)
            
            _drawGlyph(thisFont, glyph)
            
            if not keepWords:
                xAdvance += (glyph.width + tracking + kerningValue)*sc
                kerningValue = 0
                previousGlyph = glyph
                previousGlyphGroups = glyphGroups
            elif keepWords and (glyphName != '\n'):
                xAdvance += (wordLetterOffset + spaceWidth + kerningValue)*sc
                wordLetterOffset = 0 
                kerningValue = 0
                previousGlyph = glyph
                previousGlyphGroups = glyphGroups
            elif keepWords and (glyphName == '\n'):
                xAdvance = 0
                kerningValue = 0
                wordLetterOffset = 0
                yAdvance += (UPM*_line_Height)*sc
                previousGlyph = None
                previousGlyphGroups = None
            
            restore()
            
            glyphStop = time()
            glyphDrawingTime += (glyphStop-glyphStart) * 1000
            
        print 'average glyph drawing %0.2f ms, total %0.2f ms, %s glyphs drawn' % (glyphDrawingTime/nbrOfGlyphs, glyphDrawingTime, nbrOfGlyphs)
Example #22
0
def _decompose(glyph):
    components = glyph.components
    font = glyph.getParent()
    decomposedGlyph = RGlyph()
    
    if font is not None:
        for component in components:
            decomponent = RGlyph()
            decomponent.appendGlyph(font[component.baseGlyph])
            decomponent.scale((component.scale[0], component.scale[1]))
            decomponent.move((component.offset[0], component.offset[1]))
            decomposedGlyph.appendGlyph(decomponent)
        for contour in glyph.contours:
            decomposedGlyph.appendContour(contour)
        decomposedGlyph.width = glyph.width
        
    return decomposedGlyph
Example #23
0
def makeGlyph(glyphList, font, message, mark, saveBackup):
    # Initialize the progress bar
    tickCount = len(glyphList)
    bar = ProgressBar(message, tickCount)
    tick = 0

    for item in glyphList:
        glyphName, advanceWidth, components = item

        # If the font has the glyph, lots of checking is required to see if changes have been made
        if font.has_key(glyphName):
            glyph = font[glyphName]

            #Build new glyph for comparisons
            newGlyph = RGlyph()
            count = 0
            while count < len(components):
                component, x, y = components[count]
                newGlyph.appendComponent(component, offset=(x, y))
                count = count + 1
            newGlyph.width = advanceWidth

            # Make digest of the new glyph
            pointPen = DigestPointPen()
            newGlyph.drawPoints(pointPen)
            newDigest = pointPen.getDigest()

            # Make digest of the old glyph
            pointPen = DigestPointPen()
            glyph.drawPoints(pointPen)
            oldDigest = pointPen.getDigest()

            # Check the advance width
            if glyph.width != advanceWidth:
                glyph.width = advanceWidth
                if mark == 1:
                    glyph.mark = 200

            # If the digests don't match, rebuild components
            if oldDigest is not newDigest:
                if saveBackup == 1:
                    backupName = glyph.name + '.bkup'
                    font.insertGlyph(glyph, name=backupName)
                glyph.clearComponents()
                count = 0
                while count < len(components):
                    component, x, y = components[count]
                    glyph.appendComponent(component, offset=(x, y))
                    count = count + 1
                if mark == 1:
                    glyph.mark = 200

            # Clean up things
            glyph.update()
            bar.tick(tick)
            tick = tick + 1

        # If the glyph is not in the font, build a new glyph
        else:
            font.newGlyph(glyphName, clear=True)
            glyph = font[glyphName]
            glyph.width = advanceWidth
            count = 0
            while count < len(components):
                component, x, y = components[count]
                glyph.appendComponent(component, offset=(x, y))
                count = count + 1
            if mark == 1:
                glyph.mark = 300
            glyph.update()
            bar.tick(tick)
            tick = tick + 1
    bar.close()
Example #24
0
        def filterGroup(glyph, font=None, **overrideGlobalArguments):
            globalArguments = {
                self.splitSubfilterArgumentName(argumentName):
                self.arguments[argumentName]
                for argumentName in self.arguments
            }
            for key in overrideGlobalArguments:
                _subfilterName_, _overrideArgumentName_, _filterOrder_ = self.splitSubfilterArgumentName(
                    key)
                if (_subfilterName_, _overrideArgumentName_) != (None, None):
                    globalArguments[(
                        _subfilterName_, _overrideArgumentName_,
                        _filterOrder_)] = overrideGlobalArguments[key]

            subfilters = [(self.getSubfilter(subfilterName), mode, source)
                          for subfilterName, mode, source in self.subfilters]
            error = False
            canvasGlyph = RGlyph()
            canvasPen = canvasGlyph.getPen()
            canvasGlyph.width = glyph.width
            glyph.draw(canvasPen)

            steps = []

            for i, (currentFilter, mode, source) in enumerate(subfilters):

                if error == True:
                    continue

                if source is None:
                    sourceGlyph = canvasGlyph
                else:
                    try:
                        sourceGlyph = steps[source]
                    except:
                        layerGlyph = glyph.getLayer(source)
                        if len(layerGlyph) > 0:
                            sourceGlyph = RGlyph()
                            pen = sourceGlyph.getPen()
                            layerGlyph.draw(pen)
                        else:
                            sourceGlyph = canvasGlyph

                sourceGlyph.name = glyph.name

                arguments = {
                    argumentName:
                    globalArguments[(subfilterName, argumentName, filterOrder)]
                    for subfilterName, argumentName, filterOrder in
                    globalArguments
                    if subfilterName == currentFilter.name and filterOrder == i
                }
                processedGlyph = currentFilter.filterGlyph(
                    sourceGlyph, arguments)

                steps.append(processedGlyph)

                if mode in ['union', 'difference', 'intersection', 'xor']:
                    try:
                        b1 = BooleanGlyph(canvasGlyph)
                        b2 = BooleanGlyph(processedGlyph)
                        operation = getattr(b1, mode)
                        processedGlyph = operation(b2)
                    except:
                        error = True

                if mode != 'add':
                    canvasGlyph.clear()

                processedGlyph.draw(canvasPen)

            if error == True:
                canvasGlyph = ErrorGlyph()
            elif error == False:
                canvasGlyph.name = glyph.name

            canvasGlyph.unicode = glyph.unicode
            if canvasGlyph.width is None:
                canvasGlyph.width = glyph.width
            return canvasGlyph
        def filterGroup(glyph, font=None, **overrideGlobalArguments):
            globalArguments = {
                self.splitSubfilterArgumentName(argumentName):
                self.arguments[argumentName]
                for argumentName in self.arguments
            }
            for key in overrideGlobalArguments:
                _subfilterName_, _overrideArgumentName_, _filterOrder_ = self.splitSubfilterArgumentName(
                    key)
                if (_subfilterName_, _overrideArgumentName_) != (None, None):
                    globalArguments[(
                        _subfilterName_, _overrideArgumentName_,
                        _filterOrder_)] = overrideGlobalArguments[key]

            subfilters = [(self.getSubfilter(subfilterName), mode, source)
                          for subfilterName, mode, source in self.subfilters]
            error = False
            canvasGlyph = RGlyph()
            canvasPen = canvasGlyph.getPen()
            canvasGlyph.width = glyph.width
            glyph.draw(canvasPen)

            steps = []

            for i, (currentFilter, mode, source) in enumerate(subfilters):

                if error == True:
                    continue

                if not source:
                    sourceGlyph = canvasGlyph
                else:
                    try:
                        sourceGlyph = steps[source - 1]
                    except:
                        layerGlyph = glyph.getLayer(source)
                        if len(layerGlyph) > 0:
                            sourceGlyph = RGlyph()
                            pen = sourceGlyph.getPen()
                            layerGlyph.draw(pen)
                        else:
                            sourceGlyph = canvasGlyph

                sourceGlyph.name = glyph.name

                arguments = {
                    argumentName:
                    globalArguments[(subfilterName, argumentName, filterOrder)]
                    for subfilterName, argumentName, filterOrder in
                    globalArguments
                    if subfilterName == currentFilter.name and filterOrder == i
                }
                processedGlyph = currentFilter.filterGlyph(
                    sourceGlyph, arguments)

                if mode in ['union', 'difference', 'intersection', 'xor']:
                    try:
                        # collectedComponents = [component for component in processedGlyph.components]
                        b1 = BooleanGlyph(canvasGlyph)
                        b2 = BooleanGlyph(processedGlyph)
                        operation = getattr(b1, mode)
                        b3 = operation(b2)
                        processedGlyph = RGlyph()
                        processedPen = processedGlyph.getPen()
                        b3.draw(processedPen)
                        # for component in collectedComponents:
                        #     processedGlyph.appendComponent(component.baseGlyph, component.offset, component.scale)
                    except:
                        error = True

                steps.append(processedGlyph)

                if mode == 'ignore' and len(steps) > 1:
                    processedGlyph = steps[-2]
                elif mode == 'ignore':
                    processedGlyph = sourceGlyph

                if mode != 'add':
                    canvasGlyph.clear()

                processedGlyph.draw(canvasPen)

                if processedGlyph.width:
                    canvasGlyph.width = processedGlyph.width

            if error == True:
                canvasGlyph = ErrorGlyph()
            elif error == False:
                cleanPen = FilterPointPen(font)
                canvasGlyph.drawPoints(cleanPen)
                canvasGlyph.clearContours()
                canvasPointPen = canvasGlyph.getPointPen()
                cleanPen.extract(canvasPointPen)
                canvasGlyph.name = glyph.name

            canvasGlyph.unicode = glyph.unicode
            if canvasGlyph.width is None:
                canvasGlyph.width = glyph.width
            return canvasGlyph
Example #26
0
    def set(self, glyphInput, keepWords=False):
        thisFont = self.thisFont
        kerning = self.kerning
        fontKeys = thisFont.keys()
        if isinstance(glyphInput, str) or isinstance(glyphInput, unicode):
            glyphRecord = self.stringToGlyphs(glyphInput)
        elif isinstance(glyphInput, list):
            glyphRecord = glyphInput

        suffixes = self.settings['suffix']
        if len(suffixes) > 0:
            for i, glyphName in enumerate(glyphRecord):
                for suffix in suffixes:
                    if glyphName + suffix in fontKeys:
                        glyphRecord[i] = glyphName + suffix

        kernGroups = self.getKernGroups(glyphRecord)
        nbrOfGlyphs = len(glyphRecord)
        UPM = thisFont.info.unitsPerEm
        descender = thisFont.info.descender
        ascender = thisFont.info.ascender
        capHeight = thisFont.info.capHeight
        xHeight = thisFont.info.xHeight

        pointSize = self.type['size']
        _line_Height = self.type['_line_Height']
        tracking = self.type['tracking']
        color = self.type['color'][0:]
        alpha = self.type['alpha']
        x, y, width, height = self.canvas['posSize']

        sc = pointSize / UPM
        xAdvance = yAdvance = 0
        kerningValue = 0
        # exceed allowance: to which extent can a word go beyond bounds
        eA = 0.97
        wordLetterOffset = 0
        spaceWidth = thisFont['space'].width
        glyphGroups = []
        previousGlyph = None
        previousGlyphGroups = []
        wordGlyph = RGlyph()
        wordGlyph.name = ''
        glyphDrawingTime = 0
        wordKerning = []

        useKerning = self.settings['useKerning']
        showKerning = self.settings['showKerning']
        showGlyphBox = self.settings['showGlyphBox']
        showFrame = self.settings['showFrame']
        pageStamp = self.settings['pageStamp']

        newPage(*self.formats[self.preset])

        if showFrame: self.showFrame()
        if pageStamp: self.pageStamp()

        # compensate for upward y coordinates
        xPos = x
        yPos = y + height - ((UPM + descender) * sc)
        translate(xPos, yPos)

        for i, glyphName in enumerate(glyphRecord):

            # filtering missing glyphs
            if (glyphName not in fontKeys) and (glyphName != '\n'):
                if '.notdef' in fontKeys:
                    glyphName = '.notdef'
                else:
                    continue

            # skip spaces at the start of a new line
            if (glyphName == 'space') and (xAdvance == 0) and (wordLetterOffset
                                                               == 0):
                continue

            if glyphName != '\n':
                glyph = thisFont[glyphName]

            # check for need of a new line
            if ((glyphName == '\n') and (not keepWords)) or \
               (xAdvance + (glyph.width*sc*eA) >= width):
                xAdvance = 0
                kerningValue = 0
                yAdvance += (UPM * _line_Height) * sc
                _newLine = False
                previousGlyph = None
                previousGlyphGroups = None
                if (glyphName == '\n'):
                    continue

            # kerning
            if glyphName in kernGroups.keys():
                glyphGroups = kernGroups[glyphName]
                # filter out non kern groups
                glyphGroups = [
                    group for group in glyphGroups
                    if ('MMK' in group) or ('kern' in group)
                ]

                if (previousGlyph is not None) and useKerning:
                    for group in glyphGroups:
                        for prevGroup in previousGlyphGroups:
                            if kerning[(prevGroup, group)] is not None:
                                kerningValue = kerning[(prevGroup, group)]


#            glyphStart = time()

# if word wrap
            if keepWords:
                # add each glyph of a word to the wordGlyph and skip the drawing
                # add metrics of each glyph to the wordGlyph
                if (glyphName != 'space') and (glyphName !=
                                               '\n') and (i < nbrOfGlyphs - 1):

                    # draw kerning if word wrap
                    if showKerning and (kerningValue != 0):
                        save()
                        scale(sc)
                        fill(1, 0, 0, 0.5)
                        thisKern = BezierPath()
                        thisKern.moveTo((wordLetterOffset, descender))
                        thisKern.lineTo((wordLetterOffset, ascender))
                        thisKern.lineTo(
                            (wordLetterOffset + kerningValue, ascender))
                        thisKern.lineTo(
                            (wordLetterOffset + kerningValue, descender))
                        thisKern.closePath()
                        wordKerning.append(thisKern)
                        restore()

                    if len(glyph.components) > 0:
                        glyph = _decompose(glyph)
                    wordGlyph.appendGlyph(glyph,
                                          (wordLetterOffset + kerningValue, 0))
                    wordGlyph.width += (glyph.width + tracking + kerningValue)
                    wordGlyph.name += glyphName
                    wordLetterOffset += (glyph.width + tracking + kerningValue)
                    previousGlyph = glyph
                    previousGlyphGroups = glyphGroups
                    kerningValue = 0

                    continue

                # when a space is hit, or if it’s the end of the text
                # the wordglyph is passed as main glyph to be drawn
                # check if the word doesn’t exceed boundaries
                elif (glyphName
                      == 'space') or (glyphName
                                      == '\n') or (i == nbrOfGlyphs - 1):
                    if (i == nbrOfGlyphs - 1) and (glyphName != '\n'):

                        if len(glyph.components) > 0:
                            glyph = _decompose(glyph)
                        wordGlyph.appendGlyph(
                            glyph, (wordLetterOffset + kerningValue, 0))
                        wordGlyph.width += (glyph.width + tracking)
                        wordGlyph.name += glyphName
                    if glyphName != '\n':
                        previousGlyph = glyph
                        previousGlyphGroups = glyphGroups
                    glyph = wordGlyph

                    wordGlyph = RGlyph()
                    wordGlyph.name = ''
                    wordLetterOffset += tracking + kerningValue
                    if (xAdvance + (glyph.width * sc * eA) >= width):
                        xAdvance = 0
                        kerningValue = 0
                        yAdvance += (UPM * _line_Height) * sc

            # check for need of a new page
            if yAdvance + (UPM * sc) >= height:
                newPage()
                if showFrame: self.showFrame()
                if pageStamp: self.pageStamp()
                translate(xPos, yPos)
                xAdvance = 0
                yAdvance = 0
                kerningValue = 0

            # Drawing, yay!
            save()
            if not keepWords:
                translate(xAdvance + (kerningValue * sc), -yAdvance)
            elif keepWords:
                translate(xAdvance, -yAdvance)
            scale(sc)

            # draw kerning if no word wrap
            if showKerning:
                save()
                fill(1, 0, 0, 0.5)
                if not keepWords:
                    if kerningValue > 0:
                        fill(.2, .9, 0, 0.5)
                    rect(0, descender, -kerningValue, UPM)
                elif keepWords:
                    for kern in wordKerning:
                        drawPath(kern)
                wordKerning = []
                restore()

            # draw glyphBox
            if showGlyphBox:
                glyphWidth = glyph.width
                save()
                fill()
                stroke(.5)
                rect(0, descender, glyphWidth, UPM)
                for h, c in [(0, (.5, )), (xHeight, (.5, .9, 0)),
                             (capHeight, (.1, .4, .9))]:
                    stroke(*c)
                    line((0, h), (glyphWidth, h))
                restore()

            # glyph color
            if len(color) == 3:
                fill(*color + (alpha, ))
                if alpha < 1: stroke(*color)
            elif len(color) == 4:
                cmykFill(*color + (alpha, ))
                if alpha < 1: cmykStroke(*color)
            else:
                fill(0)
                if alpha < 1: stroke(0)

            glyphStart = time()
            glyph.setParent(thisFont)

            _drawGlyph(glyph)

            if not keepWords:
                xAdvance += (glyph.width + tracking + kerningValue) * sc
                kerningValue = 0
                previousGlyph = glyph
                previousGlyphGroups = glyphGroups
            elif keepWords and (glyphName != '\n'):
                xAdvance += (wordLetterOffset + spaceWidth + kerningValue) * sc
                wordLetterOffset = 0
                kerningValue = 0
                previousGlyph = glyph
                previousGlyphGroups = glyphGroups
            elif keepWords and (glyphName == '\n'):
                xAdvance = 0
                kerningValue = 0
                wordLetterOffset = 0
                yAdvance += (UPM * _line_Height) * sc
                previousGlyph = None
                previousGlyphGroups = None

            restore()

            glyphStop = time()
            glyphDrawingTime += (glyphStop - glyphStart) * 1000

        print 'average glyph drawing %0.2f ms, total %0.2f ms, %s glyphs drawn' % (
            glyphDrawingTime / nbrOfGlyphs, glyphDrawingTime, nbrOfGlyphs)
Example #27
0
def _decompose(glyph):
    components = glyph.components
    font = glyph.getParent()
    decomposedGlyph = RGlyph()

    if font is not None:
        for component in components:
            decomponent = RGlyph()
            decomponent.appendGlyph(font[component.baseGlyph])
            decomponent.scale((component.scale[0], component.scale[1]))
            decomponent.move((component.offset[0], component.offset[1]))
            decomposedGlyph.appendGlyph(decomponent)
        for contour in glyph.contours:
            decomposedGlyph.appendContour(contour)
        decomposedGlyph.width = glyph.width

    return decomposedGlyph
Example #28
0
def freezeGlyph(glyph):
    """Return a copy of a glyph, with components decomposed and all overlap removed."""

    toRFGlyph = RGlyph()
    toRFpen = toRFGlyph.getPen()
    glyph.draw(toRFpen)

    if len(glyph.components):
        decomposedComponents = extractComposites(glyph)
        decomposedComponents.draw(toRFpen)

    singleContourGlyph = RGlyph()
    singleContourGlyph.width = glyph.width
    singleContourGlyph.name = glyph.name
    pointPen = singleContourGlyph.getPointPen()

    if len(toRFGlyph.contours) > 1:

        try:
            booleanGlyphs = []

            for c in toRFGlyph.contours:
                if len(c) > 1:
                    b = BooleanGlyph()
                    pen = b.getPen()
                    c.draw(pen)
                    booleanGlyphs.append(b)

            finalBooleanGlyph = reduce(lambda g1, g2: g1 | g2, booleanGlyphs)
            finalBooleanGlyph.drawPoints(pointPen)

        except:
            toRFGlyph.drawPoints(pointPen)
    else:
        toRFGlyph.drawPoints(pointPen)

    return singleContourGlyph
        def filterGroup(glyph, font=None, **overrideGlobalArguments):
            globalArguments = {self.splitSubfilterArgumentName(argumentName): self.arguments[argumentName] for argumentName in self.arguments}
            for key in overrideGlobalArguments:
                _subfilterName_, _overrideArgumentName_, _filterOrder_ = self.splitSubfilterArgumentName(key)
                if (_subfilterName_, _overrideArgumentName_) != (None, None):
                    globalArguments[(_subfilterName_, _overrideArgumentName_, _filterOrder_)] = overrideGlobalArguments[key]

            subfilters = [(self.getSubfilter(subfilterName), mode, source) for subfilterName, mode, source in self.subfilters]
            error = False
            canvasGlyph = RGlyph()
            canvasPen = canvasGlyph.getPen()
            canvasGlyph.width = glyph.width
            glyph.draw(canvasPen)

            steps = []

            for i, (currentFilter, mode, source) in enumerate(subfilters):

                if error == True:
                    continue

                if not source:
                    sourceGlyph = canvasGlyph
                else:
                    try:
                        sourceGlyph = steps[source-1]
                    except:
                        layerGlyph = glyph.getLayer(source)
                        if len(layerGlyph) > 0:
                            sourceGlyph = RGlyph()
                            pen = sourceGlyph.getPen()
                            layerGlyph.draw(pen)
                        else:
                            sourceGlyph = canvasGlyph

                sourceGlyph.name = glyph.name

                arguments = {argumentName: globalArguments[(subfilterName, argumentName, filterOrder)] for subfilterName, argumentName, filterOrder in globalArguments if subfilterName == currentFilter.name and filterOrder == i}
                processedGlyph = currentFilter.filterGlyph(sourceGlyph, arguments)

                if mode in ['union', 'difference', 'intersection', 'xor']:
                    try:
                        # collectedComponents = [component for component in processedGlyph.components]
                        b1 = BooleanGlyph(canvasGlyph)
                        b2 = BooleanGlyph(processedGlyph)
                        operation = getattr(b1, mode)
                        b3 = operation(b2)
                        processedGlyph = RGlyph()
                        processedPen = processedGlyph.getPen()
                        b3.draw(processedPen)
                        # for component in collectedComponents:
                        #     processedGlyph.appendComponent(component.baseGlyph, component.offset, component.scale)
                    except:
                        error = True

                steps.append(processedGlyph)

                if mode == 'ignore' and len(steps) > 1:
                    processedGlyph = steps[-2]
                elif mode == 'ignore':
                    processedGlyph = sourceGlyph

                if mode != 'add':
                    canvasGlyph.clear()

                processedGlyph.draw(canvasPen)

                if processedGlyph.width:
                    canvasGlyph.width = processedGlyph.width

            if error == True:
                canvasGlyph = ErrorGlyph()
            elif error == False:
                cleanPen = FilterPointPen(font)
                canvasGlyph.drawPoints(cleanPen)
                canvasGlyph.clearContours()
                canvasPointPen = canvasGlyph.getPointPen()
                cleanPen.extract(canvasPointPen)
                canvasGlyph.name = glyph.name


            canvasGlyph.unicode = glyph.unicode
            if canvasGlyph.width is None:
                canvasGlyph.width = glyph.width
            return canvasGlyph
Example #30
0
    if negativeTracking:
        tracking = -tracking


#################
#################

def _drawGlyph(glyph):
    path = glyph.naked().getRepresentation("defconAppKit.NSBezierPath")
    drawPath(path)
    
def _decompose(glyph):
    components = glyph.components
    font = glyph.getParent()
    decomposedGlyph = RGlyph()
    
    if font is not None:
        for component in components:
            decomponent = RGlyph()
            decomponent.appendGlyph(font[component.baseGlyph])
            decomponent.scale((component.scale[0], component.scale[1]))
            decomponent.move((component.offset[0], component.offset[1]))
            decomposedGlyph.appendGlyph(decomponent)
        for contour in glyph.contours:
            decomposedGlyph.appendContour(contour)
        decomposedGlyph.width = glyph.width
        
    return decomposedGlyph

class TypeSetter(object):