def _compileFeatureFont(self, showReport=True):
     # reposition the text field
     self.glyphLineInput.setPosSize(self.glyphLineInputPosSizeWithSpinner)
     self.glyphLineInput.getNSTextField().superview().display()
     # start the progress
     self.glyphLineProgressSpinner.start()
     # compile
     path = tempfile.mkstemp()[1]
     compiler = EmptyOTFCompiler()
     ## clean up
     if self.font.info.openTypeOS2WinDescent is not None and self.font.info.openTypeOS2WinDescent < 0:
         self.font.info.openTypeOS2WinDescent = abs(self.font.info.openTypeOS2WinDescent)
     self.font.info.postscriptNominalWidthX = None
     reports = compiler.compile(self.font, path)
     # load the compiled font
     if os.path.exists(path) and reports["makeotf"] is not None and "makeotfexe [FATAL]" not in reports["makeotf"]:
         self.featureFont = FeatureFont(path)
     else:
         self.featureFont = None
     
         if showReport:
             report = []
             if reports["makeotf"] is not None:
                 for line in reports["makeotf"].splitlines():
                     if line.startswith("makeotfexe [NOTE] Wrote new font file "):
                         continue
                     report.append(line)
             self.showMessage("Error while compiling features", "\n".join(report))
             
     # stop the progress
     self.glyphLineProgressSpinner.stop()
     # color the update button
     self.glyphLineUpdateButton.enable(False)
     # reposition the text field
     self.glyphLineInput.setPosSize(self.glyphLineInputPosSize)
 def set_font(self, font=None):
     
     # open UFO with defcon
     if font is not None:
         font_path = expanduser(font[0])
         self.font = Font(font_path)
     
         # open OTF with compositor
         if font[1] is None:
             shaping_font_path = None
             self.shaping_font = None
         else:
             shaping_font_path = expanduser(font[1])
             self.shaping_font = FeatureFont(shaping_font_path)
     else:
         self.font = None
         self.shaping_font = None
     
     if self.font is not None:
         self.upm = self.font.info.unitsPerEm
         self.desc = self.font.info.descender
         self.x_height = self.font.info.xHeight
         self.cap_height = self.font.info.capHeight
         self.asc = self.font.info.ascender
         self.angle = self.font.info.italicAngle
     
     else:
         self.upm = 1000
         self.desc = -250
         self.x_height = 500
         self.cap_height = 700
         self.asc = 750
         self.angle = 0
Exemple #3
0
    def _compileFeatureFont(self, showReport=True):
        # reposition the text field
        self.glyphLineInput.setPosSize(self.glyphLineInputPosSizeWithSpinner)
        self.glyphLineInput.getNSTextField().superview().display()
        # start the progress
        self.glyphLineProgressSpinner.start()
        # compile
        path = tempfile.mkstemp()[1]
        compiler = EmptyOTFCompiler()
        # clean up
        if self.font.info.openTypeOS2WinDescent is not None and self.font.info.openTypeOS2WinDescent < 0:
            self.font.info.openTypeOS2WinDescent = abs(self.font.info.openTypeOS2WinDescent)
        self.font.info.postscriptNominalWidthX = None
        options = FontCompilerOptions()
        options.outputPath = path
        options.fdk = EmbeddedFDK()
        reports = compiler.compile(self.font, options)
        # load the compiled font
        if os.path.exists(path) and reports["makeotf"] is not None and "makeotfexe [FATAL]" not in reports["makeotf"]:
            self.featureFont = FeatureFont(path)
        else:
            self.featureFont = None

            if showReport:
                report = []
                if reports["makeotf"] is not None:
                    for line in reports["makeotf"].splitlines():
                        if line.startswith("makeotfexe [NOTE] Wrote new font file "):
                            continue
                        report.append(line)
                self.showMessage("Error while compiling features", "\n".join(report))

        # stop the progress
        self.glyphLineProgressSpinner.stop()
        # color the update button
        window = self.w.getNSWindow()
        window.setDefaultButtonCell_(None)
        # self.glyphLineUpdateButton.enable(False)
        # reposition the text field
        self.glyphLineInput.setPosSize(self.glyphLineInputPosSize)
class FeatureTester(BaseWindowController):

    def __init__(self, font):
        if font is None:
            print "A open UFO is needed"
            return
        roboFabFont = font
        font = font.naked()
        self.font = font
        self.featureFont = None

        topHeight = 40
        left = 160

        self.w = Window((700, 400), "Feature Preview", minSize=(300, 300))

        previewGroup = Group((0, 0, -0, -0))
        self.glyphLineInputPosSize = (10, 10, -85, 22)
        self.glyphLineInputPosSizeWithSpinner = (10, 10, -106, 22)
        previewGroup.glyphNameInput = self.glyphLineInput = GlyphSequenceEditText(self.glyphLineInputPosSize, font, callback=self.glyphLineViewInputCallback)
        previewGroup.progressSpinner = self.glyphLineProgressSpinner = ProgressSpinner((-98, 13, 16, 16), sizeStyle="small")
        previewGroup.updateButton = self.glyphLineUpdateButton = Button((-75, 11, -10, 20), "Update", callback=self.updateFeatureFontCallback)

        self.w.pg = previewGroup

        # tab container
        self.w.previewTabs = Tabs((left, topHeight, -0, -0), ["Preview", "Records"], showTabs=False)
        # line view
        self.w.previewTabs[0].lineView = self.glyphLineView = GlyphLineView((0, 0, -0, -0), showPointSizePlacard=True)
        # records
        columnDescriptions = [
            dict(title="Name", width=100),
            dict(title="XP", width=50),
            dict(title="YP", width=50),
            dict(title="XA", width=50),
            dict(title="YA", width=50),
            dict(title="Alternates", width=100)
        ]
        self.w.previewTabs[1].recordsList = self.glyphRecordsList = List((0, 0, -0, -0), [], columnDescriptions=columnDescriptions,
                showColumnTitles=True, drawVerticalLines=True, drawFocusRing=False)
        # controls
        self.w.controlsView = self.glyphLineControls = OpenTypeControlsView((0, topHeight, left+1, 0), self.glyphLineViewControlsCallback)

        self.font.addObserver(self, "_fontChanged", "Font.Changed")

        self.w.setDefaultButton(self.glyphLineUpdateButton)
        self.w.bind("close", self.windowClose)
        self.setUpBaseWindowBehavior()

        document = roboFabFont.document()
        if document is not None:
            document.addWindowController_(self.w.getNSWindowController())

        self.w.open()

        self.updateFeatureFontCallback(None)

    def windowClose(self, sender):
        self.destroyFeatureFont()
        self.font.removeObserver(self, "Font.Changed")

    def destroyFeatureFont(self):
        if self.featureFont is not None:
            path = self.featureFont.path
            self.featureFont = None
            os.remove(path)

    def _fontChanged(self, notification):
        self.w.setDefaultButton(self.glyphLineUpdateButton)
        # self.glyphLineUpdateButton.enable(True)

    def glyphLineViewInputCallback(self, sender):
        self.updateGlyphLineView()

    def updateFeatureFontCallback(self, sender):
        self._compileFeatureFont()
        self.updateGlyphLineViewViewControls()
        self.updateGlyphLineView()

    def glyphLineViewControlsCallback(self, sender):
        self.updateGlyphLineView()

    def _compileFeatureFont(self, showReport=True):
        # reposition the text field
        self.glyphLineInput.setPosSize(self.glyphLineInputPosSizeWithSpinner)
        self.glyphLineInput.getNSTextField().superview().display()
        # start the progress
        self.glyphLineProgressSpinner.start()
        # compile
        path = tempfile.mkstemp()[1]
        compiler = EmptyOTFCompiler()
        options = FontCompilerOptions()
        options.fdk = CurrentFDK()
        options.outputPath = path
        # clean up
        if self.font.info.openTypeOS2WinDescent is not None and self.font.info.openTypeOS2WinDescent < 0:
            self.font.info.openTypeOS2WinDescent = abs(self.font.info.openTypeOS2WinDescent)
        self.font.info.postscriptNominalWidthX = None
        reports = compiler.compile(self.font, options)
        # load the compiled font
        if os.path.exists(path) and reports["makeotf"] is not None and "makeotfexe [FATAL]" not in reports["makeotf"]:
            self.featureFont = FeatureFont(path)
        else:
            self.featureFont = None

            if showReport:
                report = []
                if reports["makeotf"] is not None:
                    for line in reports["makeotf"].splitlines():
                        if line.startswith("makeotfexe [NOTE] Wrote new font file "):
                            continue
                        report.append(line)
                self.showMessage("Error while compiling features", "\n".join(report))

        # stop the progress
        self.glyphLineProgressSpinner.stop()
        # color the update button
        window = self.w.getNSWindow()
        window.setDefaultButtonCell_(None)
        # self.glyphLineUpdateButton.enable(False)
        # reposition the text field
        self.glyphLineInput.setPosSize(self.glyphLineInputPosSize)

    def updateGlyphLineView(self):
        # get the settings
        settings = self.glyphLineControls.get()
        # set the display mode
        mode = settings["mode"]
        if mode == "preview":
            self.w.previewTabs.set(0)
        else:
            self.w.previewTabs.set(1)
        # set the direction
        self.glyphLineView.setRightToLeft(settings["rightToLeft"])
        # get the typed glyphs
        glyphs = self.glyphLineInput.get()
        # set into the view
        case = settings["case"]
        if self.featureFont is None:
            # convert case
            if case != "unchanged":
                # the case converter expects a slightly
                # more strict set of mappings than the
                # ones provided in font.unicodeData.
                # so, make them.
                cmap = {}
                reversedCMAP = {}
                for uniValue, glyphName in self.font.unicodeData.items():
                    cmap[uniValue] = glyphName[0]
                    reversedCMAP[glyphName[0]] = [uniValue]
                # transform to glyph names
                glyphNames = [glyph.name for glyph in glyphs]
                # convert
                glyphNames = convertCase(case, glyphNames, cmap, reversedCMAP, None, ".notdef")
                # back to glyphs
                glyphs = [self.font[glyphName] for glyphName in glyphNames if glyphName in self.font]
            # set the glyphs
            self.glyphLineView.set(glyphs)
            records = [dict(Name=glyph.name, XP=0, YP=0, XA=0, YA=0, Alternates="") for glyph in glyphs]
            self.glyphRecordsList.set(records)
        else:
            # get the settings
            script = settings["script"]
            language = settings["language"]
            rightToLeft = settings["rightToLeft"]
            case = settings["case"]
            for tag, state in settings["gsub"].items():
                self.featureFont.gsub.setFeatureState(tag, state)
            for tag, state in settings["gpos"].items():
                self.featureFont.gpos.setFeatureState(tag, state)
            # convert to glyph names
            glyphNames = [glyph.name for glyph in glyphs]
            # process
            glyphRecords = self.featureFont.process(glyphNames, script=script, langSys=language, rightToLeft=rightToLeft, case=case)
            # set the UFO's glyphs into the records
            finalRecords = []
            for glyphRecord in glyphRecords:
                if glyphRecord.glyphName not in self.font:
                    continue
                glyphRecord.glyph = self.font[glyphRecord.glyphName]
                finalRecords.append(glyphRecord)
            # set the records
            self.glyphLineView.set(finalRecords)
            records = [dict(Name=record.glyph.name, XP=record.xPlacement, YP=record.yPlacement, XA=record.xAdvance, YA=record.yAdvance, Alternates=", ".join(record.alternates)) for record in finalRecords]
            self.glyphRecordsList.set(records)

    def updateGlyphLineViewViewControls(self):
        if self.featureFont is not None:
            existingStates = self.glyphLineControls.get()
            # GSUB
            if self.featureFont.gsub is not None:
                for tag in self.featureFont.gsub.getFeatureList():
                    state = existingStates["gsub"].get(tag, False)
                    self.featureFont.gsub.setFeatureState(tag, state)
            # GPOS
            if self.featureFont.gpos is not None:
                for tag in self.featureFont.gpos.getFeatureList():
                    state = existingStates["gpos"].get(tag, False)
                    self.featureFont.gpos.setFeatureState(tag, state)
        self.glyphLineControls.setFont(self.featureFont)
Exemple #5
0
def getCachedNSBezierPath(glyph, font):
    if not hasattr(glyph, "nsBezierPath"):
        pen = CocoaPen(font)
        glyph.draw(pen)
        glyph.nsBezierPath = pen.path
    return glyph.nsBezierPath


# a path to a font
fontPath = aPathToYourFont

# a path to save the image to
imagePath = "demo.tiff"

# setup the layout engine
font = Font(fontPath)

# turn the aalt feature on so that we get any alternates
font.setFeatureState("aalt", True)

# process some text
glyphRecords = font.process(u"HERE IS SOME TEXT!")

# calculate the image size
pointSize = 50.0
offset = 20
scale = pointSize / font.info.unitsPerEm
imageWidth = sum([
    font[record.glyphName].width + record.xAdvance for record in glyphRecords
]) * scale
imageWidth = int(round(imageWidth))
Exemple #6
0
# a simple function that implements path caching
def getCachedNSBezierPath(glyph, font):
    if not hasattr(glyph, "nsBezierPath"):
        pen = CocoaPen(font)
        glyph.draw(pen)
        glyph.nsBezierPath = pen.path
    return glyph.nsBezierPath

# a path to a font
fontPath = sys.argv[1]

# a path to save the image to
imagePath = "demo.tiff"

# setup the layout engine
font = Font(fontPath)

# turn the aalt feature on so that we get any alternates
font.setFeatureState("aalt", True)
font.setFeatureState("liga", True)
font.setFeatureState("dlig", True)

# process some text
glyphRecords = font.process(u"Office flourishes!")

# calculate the image size
pointSize = 50.0
offset = 20
scale = pointSize / font.info.unitsPerEm
imageWidth = sum([font[record.glyphName].width + record.xAdvance for record in glyphRecords]) * scale
imageWidth = int(round(imageWidth))
Exemple #7
0
# a simple function that implements path caching
def getCachedNSBezierPath(glyph, font):
    if not hasattr(glyph, "nsBezierPath"):
        pen = CocoaPen(font)
        glyph.draw(pen)
        glyph.nsBezierPath = pen.path
    return glyph.nsBezierPath

# a path to a font
fontPath = aPathToYourFont

# a path to save the image to
imagePath = "demo.tiff"

# setup the layout engine
font = Font(fontPath)

# turn the aalt feature on so that we get any alternates
font.setFeatureState("aalt", True)

# process some text
glyphRecords = font.process(u"HERE IS SOME TEXT!")

# calculate the image size
pointSize = 50.0
offset = 20
scale = pointSize / font.info.unitsPerEm
imageWidth = sum([font[record.glyphName].width + record.xAdvance for record in glyphRecords]) * scale
imageWidth = int(round(imageWidth))
imageWidth += offset * 2
imageHeight = pointSize + (offset * 2)
Exemple #8
0
class FeatureTester(BaseWindowController):

    def __init__(self, font):
        if font is None:
            print "A open UFO is needed"
            return
        roboFabFont = font
        font = font.naked()
        self.font = font
        self.featureFont = None

        topHeight = 40
        left = 160

        self.w = Window((700, 400), "Feature Preview", minSize=(300, 300))

        previewGroup = Group((0, 0, -0, -0))
        self.glyphLineInputPosSize = (10, 10, -85, 22)
        self.glyphLineInputPosSizeWithSpinner = (10, 10, -106, 22)
        previewGroup.glyphNameInput = self.glyphLineInput = GlyphSequenceEditText(self.glyphLineInputPosSize, font, callback=self.glyphLineViewInputCallback)
        previewGroup.progressSpinner = self.glyphLineProgressSpinner = ProgressSpinner((-98, 13, 16, 16), sizeStyle="small")
        previewGroup.updateButton = self.glyphLineUpdateButton = Button((-75, 11, -10, 20), "Update", callback=self.updateFeatureFontCallback)

        self.w.pg = previewGroup

        # tab container
        self.w.previewTabs = Tabs((left, topHeight, -0, -0), ["Preview", "Records"], showTabs=False)
        # line view
        self.w.previewTabs[0].lineView = self.glyphLineView = GlyphLineView((0, 0, -0, -0), showPointSizePlacard=True)
        # records
        columnDescriptions = [
            dict(title="Name", width=100),
            dict(title="XP", width=50),
            dict(title="YP", width=50),
            dict(title="XA", width=50),
            dict(title="YA", width=50),
            dict(title="Alternates", width=100)
        ]
        self.w.previewTabs[1].recordsList = self.glyphRecordsList = List((0, 0, -0, -0), [], columnDescriptions=columnDescriptions,
                showColumnTitles=True, drawVerticalLines=True, drawFocusRing=False)
        # controls
        self.w.controlsView = self.glyphLineControls = OpenTypeControlsView((0, topHeight, left+1, 0), self.glyphLineViewControlsCallback)

        self.font.addObserver(self, "_fontChanged", "Font.Changed")

        self.w.setDefaultButton(self.glyphLineUpdateButton)
        self.w.bind("close", self.windowClose)
        self.setUpBaseWindowBehavior()

        document = roboFabFont.document()
        if document is not None:
            document.addWindowController_(self.w.getNSWindowController())

        self.w.open()

        self.updateFeatureFontCallback(None)

    def windowClose(self, sender):
        self.destroyFeatureFont()
        self.font.removeObserver(self, "Font.Changed")

    def destroyFeatureFont(self):
        if self.featureFont is not None:
            path = self.featureFont.path
            self.featureFont = None
            os.remove(path)

    def _fontChanged(self, notification):
        self.w.setDefaultButton(self.glyphLineUpdateButton)
        # self.glyphLineUpdateButton.enable(True)

    def glyphLineViewInputCallback(self, sender):
        self.updateGlyphLineView()

    def updateFeatureFontCallback(self, sender):
        self._compileFeatureFont()
        self.updateGlyphLineViewViewControls()
        self.updateGlyphLineView()

    def glyphLineViewControlsCallback(self, sender):
        self.updateGlyphLineView()

    def _compileFeatureFont(self, showReport=True):
        # reposition the text field
        self.glyphLineInput.setPosSize(self.glyphLineInputPosSizeWithSpinner)
        self.glyphLineInput.getNSTextField().superview().display()
        # start the progress
        self.glyphLineProgressSpinner.start()
        # compile
        path = tempfile.mkstemp()[1]
        compiler = EmptyOTFCompiler()
        # clean up
        if self.font.info.openTypeOS2WinDescent is not None and self.font.info.openTypeOS2WinDescent < 0:
            self.font.info.openTypeOS2WinDescent = abs(self.font.info.openTypeOS2WinDescent)
        self.font.info.postscriptNominalWidthX = None
        reports = compiler.compile(self.font, path)
        # load the compiled font
        if os.path.exists(path) and reports["makeotf"] is not None and "makeotfexe [FATAL]" not in reports["makeotf"]:
            self.featureFont = FeatureFont(path)
        else:
            self.featureFont = None

            if showReport:
                report = []
                if reports["makeotf"] is not None:
                    for line in reports["makeotf"].splitlines():
                        if line.startswith("makeotfexe [NOTE] Wrote new font file "):
                            continue
                        report.append(line)
                self.showMessage("Error while compiling features", "\n".join(report))

        # stop the progress
        self.glyphLineProgressSpinner.stop()
        # color the update button
        window = self.w.getNSWindow()
        window.setDefaultButtonCell_(None)
        # self.glyphLineUpdateButton.enable(False)
        # reposition the text field
        self.glyphLineInput.setPosSize(self.glyphLineInputPosSize)

    def updateGlyphLineView(self):
        # get the settings
        settings = self.glyphLineControls.get()
        # set the display mode
        mode = settings["mode"]
        if mode == "preview":
            self.w.previewTabs.set(0)
        else:
            self.w.previewTabs.set(1)
        # set the direction
        self.glyphLineView.setRightToLeft(settings["rightToLeft"])
        # get the typed glyphs
        glyphs = self.glyphLineInput.get()
        # set into the view
        case = settings["case"]
        if self.featureFont is None:
            # convert case
            if case != "unchanged":
                # the case converter expects a slightly
                # more strict set of mappings than the
                # ones provided in font.unicodeData.
                # so, make them.
                cmap = {}
                reversedCMAP = {}
                for uniValue, glyphName in self.font.unicodeData.items():
                    cmap[uniValue] = glyphName[0]
                    reversedCMAP[glyphName[0]] = [uniValue]
                # transform to glyph names
                glyphNames = [glyph.name for glyph in glyphs]
                # convert
                glyphNames = convertCase(case, glyphNames, cmap, reversedCMAP, None, ".notdef")
                # back to glyphs
                glyphs = [self.font[glyphName] for glyphName in glyphNames if glyphName in self.font]
            # set the glyphs
            self.glyphLineView.set(glyphs)
            records = [dict(Name=glyph.name, XP=0, YP=0, XA=0, YA=0, Alternates="") for glyph in glyphs]
            self.glyphRecordsList.set(records)
        else:
            # get the settings
            script = settings["script"]
            language = settings["language"]
            rightToLeft = settings["rightToLeft"]
            case = settings["case"]
            for tag, state in settings["gsub"].items():
                self.featureFont.gsub.setFeatureState(tag, state)
            for tag, state in settings["gpos"].items():
                self.featureFont.gpos.setFeatureState(tag, state)
            # convert to glyph names
            glyphNames = [glyph.name for glyph in glyphs]
            # process
            glyphRecords = self.featureFont.process(glyphNames, script=script, langSys=language, rightToLeft=rightToLeft, case=case)
            # set the UFO's glyphs into the records
            finalRecords = []
            for glyphRecord in glyphRecords:
                if glyphRecord.glyphName not in self.font:
                    continue
                glyphRecord.glyph = self.font[glyphRecord.glyphName]
                finalRecords.append(glyphRecord)
            # set the records
            self.glyphLineView.set(finalRecords)
            records = [dict(Name=record.glyph.name, XP=record.xPlacement, YP=record.yPlacement, XA=record.xAdvance, YA=record.yAdvance, Alternates=", ".join(record.alternates)) for record in finalRecords]
            self.glyphRecordsList.set(records)

    def updateGlyphLineViewViewControls(self):
        if self.featureFont is not None:
            existingStates = self.glyphLineControls.get()
            # GSUB
            if self.featureFont.gsub is not None:
                for tag in self.featureFont.gsub.getFeatureList():
                    state = existingStates["gsub"].get(tag, False)
                    self.featureFont.gsub.setFeatureState(tag, state)
            # GPOS
            if self.featureFont.gpos is not None:
                for tag in self.featureFont.gpos.getFeatureList():
                    state = existingStates["gpos"].get(tag, False)
                    self.featureFont.gpos.setFeatureState(tag, state)
        self.glyphLineControls.setFont(self.featureFont)
class FontProofer(object):
    
    def getPickedFont():
        print "Picked Font"
        print self.font
    
    def __init__(self,
            font=None,
            format_index=0,
            font_index=0,
            caps_lock=False,
            linespace=0.7,
            marginsupdown = 20,
            marginsside = 20,
            nib_simulate=False,
            nib_width_index=0,
            nib_angle=30,
            Color_Nib=False,
            send_to_plotter=False,
            features = [], # Use features that are active by default (kern, liga, calt)
        ):
        
        self.linespace = linespace
        self.format_index = format_index
        self.font_index = font_index
        self.set_font(font)    
        
        self.mark_fill = False
        self.mark_composites = False
        
        # A6 Format
        self.width = 842/2
        self.height = 595/2
        if format_index == 1:
            self.width = 595/2
            self.height = 842/2
        
        
        self.margins = {
            "top": marginsupdown,
            "bottom": marginsupdown,
            "left": marginsside,
            "right": marginsside,
        
        }
        self.breite = self.width - marginsside * 2
        self.scale = 1 
        
        self.nib_simulate = nib_simulate
        
        self.features = features
        
        if nib_width_index in pp_sizes:
            self.nib_width_pt = pp_sizes[nib_width_index]
        else:
            self.nib_width_pt = 14.173
        self.nib_width = self.nib_width_pt / self.scale
        
        self.nib_angle = radians(nib_angle)
        
        self.pen_width = 0.7 / 25.4 * 72 # mm in pt
        
        if font_index in fonts_list:
             print "Selected font: ", font_index + 1
             self.set_font(fonts_list[font_index])
        print "\nNib Simulation Parameters","\nNib Width:     ", (round((self.nib_width / 4),1))+0.1,"mm", "\nNib Angle:     ",(round((nib_angle),1)),"°","\n"
        
        self.x_pad = 10
        self.y_pad = 24
        print "Leading:       ", round(linespace*(1/0.7), 2),"\nVertical Shift:", round((marginsupdown-20)*-1,1),"\nScale-Factor:  ", round(((marginsside-260)*-1)/2.4, 1), "%","\n"
        self.Color_Nib = Color_Nib
        self.send_to_plotter = send_to_plotter
        
    
    
    
    def set_font(self, font=None):
        
        # open UFO with defcon
        if font is not None:
            font_path = expanduser(font[0])
            self.font = Font(font_path)
        
            # open OTF with compositor
            if font[1] is None:
                shaping_font_path = None
                self.shaping_font = None
            else:
                shaping_font_path = expanduser(font[1])
                self.shaping_font = FeatureFont(shaping_font_path)
        else:
            self.font = None
            self.shaping_font = None
        
        if self.font is not None:
            self.upm = self.font.info.unitsPerEm
            self.desc = self.font.info.descender
            self.x_height = self.font.info.xHeight
            self.cap_height = self.font.info.capHeight
            self.asc = self.font.info.ascender
            self.angle = self.font.info.italicAngle
        
        else:
            self.upm = 1000
            self.desc = -250
            self.x_height = 500
            self.cap_height = 700
            self.asc = 750
            self.angle = 0
    
    def new_page(self):
        newPage(self.width, self.height)
        translate(self.margins["left"], self.height - self.margins["top"] - self.asc * self.scale)
    
    def _drawGlyph(self, glyph):
        save()
        #scale(self.scale)
        
        fill(None)
        lineJoin("round")
        miterLimit(1)
        strokeWidth(self.pen_width/self.scale)
        stroke(0, 0, 0, 1)
        drawGlyph(glyph)
        if self.nib_simulate:
            if self.Color_Nib:
                stroke(1, 0, 0, 1)
            save()
            translate((self.nib_width * -0.5 * cos(self.nib_angle))*(1/self.scale), self.nib_width * -0.5 * sin(self.nib_angle)*(1/self.scale))
            drawGlyph(glyph)
            restore()
            save()
            translate((self.nib_width * 0.5 * cos(self.nib_angle))*(1/self.scale), self.nib_width * 0.5 * sin(self.nib_angle)*(1/self.scale))
            drawGlyph(glyph)
            restore()
        restore()
    
    def setText(self, my_text):
        my_list = getGlyphNamesFromString(my_text+"\n")
        
        if self.font is None:
            print "Pick a font"
            return None
        
        if self.shaping_font is None:
            glyphRecords = [SimpleGlyphRecord(n) for n in my_list]
        else:
            for tag, state in self.features:
                try:
                    self.shaping_font.gpos.setFeatureState(tag, state)
                except:
                    pass
                try:
                    self.shaping_font.gsub.setFeatureState(tag, state)
                except:
                    pass
            glyphRecords = self.shaping_font.process(
                my_list,
                script="DFLT",
                langSys="DEU",
                rightToLeft=False,
                case="unchanged",
            )
        
        # Measure lines, draw line when a \n character occurs.
        
        line_width = 0
        line_width_prev = 0
        lineGlyphRecords = []
        first_line = True
        
        for gr in glyphRecords:
            if gr.glyphName != r"\n":
                glyphname = gr.glyphName
                try:
                    glyph = self.font[glyphname]
                except KeyError:
                    print "Ignored missing glyph:", glyphname
                    glyph = None
                if glyph is not None:
                    line_width += glyph.width + gr.xAdvance
                    lineGlyphRecords.append(gr)
            else:
                #print [gr.glyphName for gr in lineGlyphRecords]
                #print "Line width:", line_width
                self.scale = self.breite / line_width
                #print "Scale:", self.scale
                if first_line:
                    self.new_page()
                    first_line = False
                else:
                    #print "Translate"
                    translate(0, -self.upm * self.scale * self.linespace)
                    #rect(0, 0, 10, 10)
                self.opticalSize()
                save()
                scale(self.scale)
                #fill(None)
                #stroke(1,0,0)
                #rect(0, 10, line_width, self.asc-10)
                #rect(0, self.desc, line_width, -self.desc-10)
                for gr in lineGlyphRecords:
                    glyphname = gr.glyphName
                    glyph = self.font[glyphname]
                    save()
                    translate(gr.xPlacement, gr.yPlacement)
                    self._drawGlyph(glyph)
                    restore()
                    translate(glyph.width + gr.xAdvance, gr.yAdvance)
                line_width = 0
                lineGlyphRecords = []
                restore()
                
        if self.send_to_plotter:
            saveImage(expanduser("~/Documents/Penplotter_Cards/Postcard_%s_%d.pdf") % (Line_1, now()))
            print "PDF saved to /Documents/Penplotter_Cards/Postcard_%s_%d.pdf" % (Line_1, now())
            print "Plotting..."
            plot("~/Desktop/temp.hpgl")

                    
    def opticalSize(self):
        fontsize_list = {
        0: ("~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/Bronco_Centerline.ufo", "~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/Bronco_black_01_.otf"),
        4: ("~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/Bronco_fourlines_01.ufo", "~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/Bronco_black_01_.otf"),
        2: ("~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/Bronco_oneline_01.ufo", "~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/Bronco_black_01_.otf"),
        1: ("~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/Bronco_Outline_01.ufo", "~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/Bronco_black_01_.otf"),
        3: ("~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/Bronco_twoline_01.ufo", "~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/Bronco_black_01_.otf"),
        #5: ("~/Documents/Schriften/_MeineSchriften/PenPlotterFaces/DrawbotSketches/fonts/petrosian_04.ufo", None),
        }
        
        if self.font_index == 2: 
            self.set_font(fontsize_list[ min( 4, int(self.scale/0.069) ) ] )
Exemple #10
0
    def _compileFeatureFont(self, showReport=True):
        # reposition the text field
        self.glyphLineInput.setPosSize(self.glyphLineInputPosSizeWithSpinner)
        self.glyphLineInput.getNSTextField().superview().display()

        # start the progress
        self.glyphLineProgressSpinner.start()

        # "before" info
        prevOpenTypeOS2WinDescent = self.font.info.openTypeOS2WinDescent
        prevPostscriptNominalWidthX = self.font.info.postscriptNominalWidthX
        prevFeaText = self.font.features.text
        prevFamilyName = self.font.info.familyName
        prevStyleName = self.font.info.styleName
        prevOpenTypeNamePreferredFamilyName = self.font.info.openTypeNamePreferredFamilyName
        prevOpenTypeNamePreferredSubfamilyName = self.font.info.openTypeNamePreferredSubfamilyName

        # tweak some values to the font generates
        if self.font.info.openTypeOS2WinDescent is not None and self.font.info.openTypeOS2WinDescent < 0:
            self.font.info.openTypeOS2WinDescent = abs(
                self.font.info.openTypeOS2WinDescent)

        self.font.info.postscriptNominalWidthX = None

        if hasFeaPyFoFum:
            self.font.features.text = compileFeatures(
                self.font.features.text,
                self.font,
                compileReferencedFiles=True)

        self.font.info.familyName = self.font.info.familyName if self.font.info.familyName else "Untitled"
        self.font.info.styleName = self.font.info.styleName if self.font.info.styleName else "Untitled"
        self.font.info.openTypeNamePreferredFamilyName = self.font.info.openTypeNamePreferredFamilyName if self.font.info.openTypeNamePreferredFamilyName else "Untitled"
        self.font.info.openTypeNamePreferredSubfamilyName = self.font.info.openTypeNamePreferredSubfamilyName if self.font.info.openTypeNamePreferredSubfamilyName else "Untitled"

        # compile
        path = tempfile.mkstemp()[1]
        compiler = EmptyOTFCompiler()
        options = FontCompilerOptions()
        options.outputPath = path
        options.fdk = EmbeddedFDK()
        reports = compiler.compile(self.font, options)

        # load the compiled font
        if os.path.exists(path) and reports[
                "makeotf"] is not None and "makeotfexe [FATAL]" not in reports[
                    "makeotf"]:
            self.featureFont = FeatureFont(path)
        else:
            self.featureFont = None

            if showReport:
                report = []
                if reports["makeotf"] is not None:
                    for line in reports["makeotf"].splitlines():
                        if line.startswith(
                                "makeotfexe [NOTE] Wrote new font file "):
                            continue
                        report.append(line)
                self.showMessage("Error while compiling features",
                                 "\n".join(report))

        # reset tweaked values
        self.font.info.openTypeOS2WinDescent = prevOpenTypeOS2WinDescent
        self.font.info.postscriptNominalWidthX = prevPostscriptNominalWidthX
        self.font.features.text = prevFeaText
        self.font.info.familyName = prevFamilyName
        self.font.info.styleName = prevStyleName
        self.font.info.openTypeNamePreferredFamilyName = prevOpenTypeNamePreferredFamilyName
        self.font.info.openTypeNamePreferredSubfamilyName = prevOpenTypeNamePreferredSubfamilyName

        # stop the progress
        self.glyphLineProgressSpinner.stop()

        # color the update button
        window = self.w.getNSWindow()
        window.setDefaultButtonCell_(None)
        # self.glyphLineUpdateButton.enable(False)
        # reposition the text field
        self.glyphLineInput.setPosSize(self.glyphLineInputPosSize)