Exemplo n.º 1
0
def downloadCurrentVersion():
    """
    Download the current version (dmg) and mount it
    """
    path = "https://github.com/typemytype/drawbot/releases/latest/download/DrawBot.dmg"
    try:
        context = ssl._create_unverified_context()
        request = Request(path, headers={'User-Agent': 'Drawbot'})
        # download and mount
        with tempfile.NamedTemporaryFile(mode='w+b') as dmgFile:
            response = urlopen(request, timeout=5, context=context)
            dmgFile.write(response.read())
            response.close()
            cmds = ["hdiutil", "attach", "-plist", dmgFile.name]
            popen = subprocess.Popen(cmds,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
            out, err = popen.communicate()
        if popen.returncode != 0:
            raise DrawBotError("Mounting failed")
        output = plistlib.loads(out)
        dmgPath = None
        for item in output["system-entities"]:
            if "mount-point" in item:
                dmgPath = item["mount-point"]
                break
        AppKit.NSWorkspace.sharedWorkspace().openFile_(dmgPath)
    except Exception:
        exc = traceback.format_exc()
        message("Something went wrong while downloading %s" % path, exc)
Exemplo n.º 2
0
    def __init__(self):

        self.font = CurrentFont()
        self.spaceCenter = None
        if self.font:
            addObserver(self, 'SpaceCenterObserver', 'spaceCenterDidOpen')
            self.spaceCenter = OpenSpaceCenter(self.font, newWindow=True)

            addObserver(self, 'pressedKey', 'spaceCenterKeyDown')
            addObserver(self, 'closeSpaceCenter', 'spaceCenterWillClose')

            # get kerning from CurrentFont and build text list
            self.pairsTextCheck = []
            self.kKeys = self.getKerningPairsRef(self.font)
            for key, gkey in self.kKeys:
                self.pairsTextCheck.append(self.returnPattern(key))

            # index of text
            self.i = 0
            self.maxi = len(self.kKeys)

            if self.pairsTextCheck:
                self.hasKerning = True
                self.spaceCenter.set(self.pairsTextCheck[self.i])
            else:
                self.hasKerning = False
                self.spaceCenter.setRaw('YOUR FONT HAS NO KERNING PAIRS -- your font has no kerning pairs')

        else:
            message('You need to open a font first!')
 def __init__(self):
     self.font = CurrentFont()
     if self.font is None:
         from vanilla.dialogs import message
         message("No Font is open.", "Open or create a font to convert groups to feature syntax groups.")
         return
     
     groupsNames = self.font.groups.keys()
     groupsNames.sort()
     
     self.w = Window((400, 400), "Feature Group Converter", minSize=(300, 300))
     
     toolbarItems = [
         dict(itemIdentifier="insert",
             label="Insert In Font",
             imageObject=insertFeatureToolbarImage(),
             callback=self.toolbarInsert,
             ),
         ]
     toolbar = self.w.addToolbar(toolbarIdentifier="GroupsToFeatureTextToolbar", toolbarItems=toolbarItems, addStandardItems=False)
     
     self.w.groupList = List((0, 0, 150, -0), groupsNames, selectionCallback=self.groupListSelectionCallback)
     self.w.feaText = DoodleFeatureTextEditor((150, 0, -0, -0), "")
     self.w.groupList.setSelection([])
             
     self.w.assignToDocument(self.font.document())
     
     self.w.open()
Exemplo n.º 4
0
    def _assignLayerToGlyph_Button_callback(self, sender):
        storageGlyphName = self.ui.w.deepComponentsEditorGroup.GlyphLayers.storageGlyphName
        StorageGlyphCurrentLayer = self.ui.w.deepComponentsEditorGroup.GlyphLayers.StorageGlyphCurrentLayer

        if storageGlyphName is None:
            message("Warning there is no selected glyph")
            return

        if not self.selectedLayerName:
            message("Warning there is no selected layer")
            return

        storageFont = self.ui.font2Storage[self.ui.font]
        layer = StorageGlyphCurrentLayer

        if not layer:
            layer = storageFont[storageGlyphName]

        layer.round()

        if self.selectedLayerName not in storageFont[storageGlyphName].lib[
                "deepComponentsLayer"]:
            storageFont.getLayer(self.selectedLayerName).insertGlyph(layer)
            storageFont[storageGlyphName].lib["deepComponentsLayer"].append(
                self.selectedLayerName)
        storageFont[storageGlyphName].update()

        self.ui.w.deepComponentsEditorGroup.GlyphLayers.layersCanvas.update()

        self.ui.w.deepComponentsEditorGroup.GlyphLayers.setSliderList()
Exemplo n.º 5
0
 def windowShouldClose(self, window):
     if self.isRunning:
         message("Window can’t be closed",
                 "The ‘pip’ process is still running.",
                 parentWindow=self.w)
         return False
     return True
Exemplo n.º 6
0
 def applicationOpenFile(self, notification):
     path = notification["path"]
     ext = notification["ext"]
     fileHandler = notification["fileHandler"]
     if ext == ".%s" % fileExtension:
         singleItems = list(getExtensionDefault("com.mechanic.singleExtensionItems"))
         try:
             with open(path, "rb") as f:
                 item = yaml.load(f.read())
         except Exception as e:
             logger.error("Cannot read '%s' file" % path)
             logger.error(e)
         try:
             ExtensionYamlItem(item)
             if item not in singleItems:
                 singleItems.append(item)
                 setExtensionDefault("com.mechanic.singleExtensionItems", singleItems)
                 title = "Opening Mechanic file."
                 text = "Added '%s' to Mechanic" % path
             else:
                 title = "Duplicate Mechanic file."
                 text = "The extension '%s' was not added to Mechanic" % path
         except Exception as e:
             logger.error("Cannot parse the file '%s'" % path)
             logger.error(e)
             title = "Failed to read the file '%s'." % path
             text = "See the output window for a detailed traceback."
         message(title, text)
         fileHandler["opened"] = True
 def generateGlyphsToFont(self, exportFont=None, layerName=None):
     font = RFont(showInterface=False) if exportFont is None else exportFont
     currentFont = self.currentFont
     filterName = self.currentFilterName
     currentFilter = self.filters[filterName]
     if currentFont is not None and len(currentFont.selectedGlyphs):
         glyphs = [
             currentFont[glyphName]
             for glyphName in currentFont.selectedGlyphNames
             if glyphName in currentFont
         ]
         for glyph in glyphs:
             if len(glyph.components) > 0:
                 for comp in glyph.components:
                     baseGlyphName = comp.baseGlyph
                     baseGlyph = currentFont[baseGlyphName]
                     baseFilteredGlyph = currentFilter(baseGlyph)
                     newFont.insertGlyph(baseFilteredGlyph, baseGlyphName)
                     newFont[
                         baseGlyphName].unicode = baseFilteredGlyph.unicode
             filteredGlyph = currentFilter(glyph)
             if filteredGlyph is not None:
                 if exportFont is None:
                     font.insertGlyph(filteredGlyph, glyph.name)
                 else:
                     glyph = font[
                         glyph.name] if layerName is None else font[
                             glyph.name].getLayer(layerName)
                     glyph.clearContours()
                     glyph.clearComponents()
                     glyph.appendGlyph(filteredGlyph)
         font.openInterface()
     else:
         message('PenBallWizard', 'No selected glyphs to generate')
Exemplo n.º 8
0
def averageWidth():
    Glyphs.clearLog()
    try:
        averageWidth = 0
        count = 0
        alreadyCheckedGlyphs = []
        msg_txt = ""
        for layer in Glyphs.font.selectedLayers:
            thisGlyph = layer.parent

            if thisGlyph.name is None: continue
            if thisGlyph.name == "None": continue
            if thisGlyph.name in alreadyCheckedGlyphs:
                continue  # this will omitt glyphs.width that was already checked

            averageWidth += layer.width
            count += 1
            print("\t", thisGlyph.name)
            msg_txt += "'" + str(thisGlyph.name) + "' " + "width: " + str(
                layer.width) + "\n"
            print("\t" "Width =>", layer.width)
            alreadyCheckedGlyphs.append(thisGlyph.name)

        averageWidth = averageWidth / count
        print("Average Width =>", averageWidth)
        msg_txt += "\n\nAverage Width: %s" % averageWidth
        vd.message(msg_txt)

    except Exception as e:
        # print error
        Glyphs.showMacroWindow()
        print("Change Width Centered Error: %s" % e)
Exemplo n.º 9
0
    def checkReqVsCase(self, required, case):
        """Check that required letters do not contradict case selection.

        This seems to be a frequent source of user error.
        Only implemented for text mode (character list), not grep.
        """

        errNotLower = "word-o-mat: Conflict: You have specified all-lowercase words, but required uppercase characters. Please revise."
        errNotUpper = "word-o-mat: Conflict: You have specified words in ALL CAPS, but required lowercase characters. Please revise."

        if self.matchMode != "grep":

            # all lowercase words -- catch caps
            if case == 1:
                for c in required:
                    if not c.islower():
                        message(errNotLower)
                        return False
                return True

            # all caps -- catch lowercase letters
            elif case == 3:
                for c in required:
                    if not c.isupper():
                        message(errNotUpper)
                        return False
                return True
        return True
Exemplo n.º 10
0
    def checkReqVsCase(self, required, case):
        """Check that required letters do not contradict case selection.

        This seems to be a frequent source of user error.
        Only implemented for text mode (character list), not grep.
        """

        errNotLower = "word-o-mat: Conflict: You have specified all-lowercase words, but required uppercase characters. Please revise."
        errNotUpper = "word-o-mat: Conflict: You have specified words in ALL CAPS, but required lowercase characters. Please revise."

        if self.matchMode != "grep":

            # all lowercase words -- catch caps
            if case == 1:
                for c in required:
                    if not c.islower():
                        message (errNotLower)
                        return False
                return True

            # all caps -- catch lowercase letters
            elif case == 3:
                for c in required:
                    if not c.isupper():
                        message (errNotUpper)
                        return False
                return True
        return True
 def generateGlyphsToFont(self, exportFont=None, layerName=None):
     font = RFont(showUI=False) if exportFont is None else exportFont
     currentFont = self.currentFont
     filterName = self.currentFilterName
     currentFilter = self.filters[filterName]
     if currentFont is not None and len(currentFont.selection):
         glyphs = [currentFont[glyphName] for glyphName in currentFont.selection if glyphName in currentFont]
         for glyph in glyphs:
             if len(glyph.components) > 0:
                 for comp in glyph.components:
                     baseGlyphName = comp.baseGlyph
                     baseGlyph = currentFont[baseGlyphName]
                     baseFilteredGlyph = currentFilter(baseGlyph)
                     newFont.insertGlyph(baseFilteredGlyph, baseGlyphName)
                     newFont[baseGlyphName].unicode = baseFilteredGlyph.unicode
             filteredGlyph = currentFilter(glyph)
             if filteredGlyph is not None:
                 if exportFont is None:
                     font.insertGlyph(filteredGlyph, glyph.name)
                 else:
                     glyph = font[glyph.name] if layerName is None else font[glyph.name].getLayer(layerName)
                     glyph.clearContours()
                     glyph.clearComponents()
                     glyph.appendGlyph(filteredGlyph)
         font.showUI()
     else:
         message(u'PenBallWizard', 'No selected glyphs to generate')
Exemplo n.º 12
0
    def __init__(self):

        self.font = CurrentFont()
        self.spaceCenter = None
        if self.font:
            addObserver(self, 'SpaceCenterObserver', 'spaceCenterDidOpen')
            self.spaceCenter = OpenSpaceCenter(self.font, newWindow=True)

            # addObserver(self, None, 'spaceCenterDraw')
            addObserver(self, 'pressedKey', 'spaceCenterKeyDown')
            addObserver(self, 'closeSpaceCenter', 'spaceCenterWillClose')

            # get kerning from CurrentFont and build text list
            self.pairsTextCheck = []
            self.kKeys = self.getKerningPairsRef(self.font)
            # get reference pairs for flipping
            self.refPairs = [pair[0] for pair in self.kKeys]

            for key, gkey in self.kKeys:
                self.pairsTextCheck.append(self.returnPattern(key))

            # index of text
            self.i = 0
            self.maxi = len(self.kKeys)

            self.spaceCenter.set(self.pairsTextCheck[self.i])

        else:
            message('You need to open a font first!')
    def send(self, sender):
        recipients = self.window.recipients.get()
        selection = [
            recipients[i] for i in self.window.recipients.getSelection()
        ]

        if selection == []:
            selection = self.window.recipients.get()

        recipients = ', '.join(selection)

        progress = ProgressWindow('', tickCount=3, parentWindow=self.window)

        try:
            tmpdir = tempfile.mkdtemp(prefix="ghostlines")

            progress.update('Generating OTF')

            # Should be controlled which options are used somewhere
            filename = os.path.join(tmpdir, self.font.info.familyName + '.otf')

            self.font.generate(format="otf",
                               path=filename,
                               decompose=True,
                               checkOutlines=True,
                               autohint=True)

            progress.update('Sending via Ghostlines')

            with open(filename, 'rb') as otf:
                params = dict(otf=otf,
                              recipients=recipients,
                              notes=self.window.notes_field.get(),
                              designer_email_address=self.window.
                              email_address_field.get())

                license_path = self.license_storage.retrieve()

                if license_path is not '' and os.path.exists(license_path):
                    with open(license_path, 'rb') as license:
                        filename = os.path.basename(license_path)
                        _, extension = os.path.splitext(license_path)
                        content_type = filetypes[extension]
                        params['license'] = (filename, license, content_type)
                        response = Ghostlines('v0.1').send(**params)
                else:
                    response = Ghostlines('v0.1').send(**params)

            if response.status_code == requests.codes.created:
                message("{} was delivered".format(self.font.info.familyName))
            else:
                print repr(response)
                message(
                    "{} could not be delivered".format(
                        self.font.info.familyName),
                    "Error code: {}\n{}".format(response.status_code,
                                                response.json()))
        finally:
            progress.close()
Exemplo n.º 14
0
    def send(self, *_):
        subscribers = self.window.subscriber_info.subscribers.get()
        subscriber_ids = [
            subscribers[i]["id"]
            for i in self.window.subscriber_info.subscribers.getSelection()
        ]
        notes = self.note_draft_storage.retrieve()
        font_family_id = self.family_id_storage.retrieve()
        license_path = self.license_storage.retrieve()

        progress = ProgressWindow('', tickCount=3, parentWindow=self.window)

        try:
            tmpdir = tempfile.mkdtemp(prefix="ghostlines")

            progress.update('Generating OTF')

            # Should be controlled which options are used somewhere
            otf_path = os.path.join(tmpdir,
                                    '{}.otf'.format(self.font.info.familyName))
            self.font.generate(format="otf",
                               path=otf_path,
                               decompose=True,
                               checkOutlines=True,
                               autohint=True)

            progress.update('Sending via Ghostlines')

            params = dict(notes=notes, font_family_id=font_family_id)

            with open(otf_path, 'rb') as otf:
                params['otfs'] = [(os.path.basename(otf_path), otf.read(),
                                   "application/octet-stream")]

            if subscriber_ids:
                params['subscriber_ids[]'] = subscriber_ids

            if self.license_exists:
                with open(license_path, 'rb') as license:
                    filename = os.path.basename(license_path)
                    _, extension = os.path.splitext(license_path)
                    content_type = filetypes[extension]
                    params['license'] = (filename, license.read(),
                                         content_type)

            token = AppStorage("accessToken").retrieve()
            response = Ghostlines('v1', token=token).create_release(**params)

            if response.status_code == requests.codes.created:
                message("{} was delivered".format(self.font.info.familyName))

                self.refresh_releases()
            else:
                ErrorMessage(
                    "{} could not be delivered".format(
                        self.font.info.familyName),
                    response.json()["errors"])
        finally:
            progress.close()
Exemplo n.º 15
0
 def testFontButtonCallback(self, sender):
     font = CurrentFont()
     if font is None:
         dialogs.message("There is no font to test.", "Open a font and try again.")
         return
     testStates = self._getSettings()
     results = getFontReport(font, testStates, format=True)
     print results
Exemplo n.º 16
0
 def checkMinVsMax(self, minLength, maxLength):
     """Check user input for minimal/maximal word length and see if it makes sense."""
     if not minLength <= maxLength:
         message(
             "word-o-mat: Confusing input for minimal/maximal word length. Please fix."
         )
         return False
     return True
Exemplo n.º 17
0
def commitInfoNote(infoNoteContent, font, fontState):
    if infoNoteContent == "":
        message("info note is blank, operation aborted")
    else:
        font.info.note = infoNoteContent
        print "saving changes on font: %s" % font.path
        font.copy().save(font.path)
        commitVersion(font, fontState)
Exemplo n.º 18
0
def main():
    font = CurrentFont()
    success, maybeFontState = getFontState(font)

    if not success:
        message("script validation failed(fix and try again):\n" + maybeFontState)
    else:
        userChecksInfoNote(font, maybeFontState)
Exemplo n.º 19
0
 def revealInstallFolderCallback(self, sender):
     if not os.path.exists(self.targetPath):
         message("The install folder does not yet exists.",
                 "Try again after installing a package.",
                 parentWindow=self.w)
     else:
         AppKit.NSWorkspace.sharedWorkspace(
         ).selectFile_inFileViewerRootedAtPath_(None, self.targetPath)
Exemplo n.º 20
0
 def checkReqVsLen(self, required, maxLength):
     """Check for conflicts between number of required characters and specified word length.
     Only implemented for text input for now.
     """
     if self.matchMode != "grep":
         if len(required) > maxLength:
             message ("word-o-mat: Conflict: Required characters exceed maximum word length. Please revise.")
             return False
     return True
Exemplo n.º 21
0
 def application_openFile_(self, app, path):
     ext = os.path.splitext(path)[-1]
     if ext.lower() == ".drawbot":
         succes, report = DrawBotPackage(path).run()
         if not succes:
             fileName = os.path.basename(path)
             message("The DrawBot package '%s' failed." % fileName, report)
         return True
     return False
Exemplo n.º 22
0
 def application_openFile_(self, app, path):
     ext = os.path.splitext(path)[-1]
     if ext.lower() == ".drawbot":
         succes, report = DrawBotPackage(path).run()
         if not succes:
             fileName = os.path.basename(path)
             message("The DrawBot package '%s' failed." % fileName, report)
         return True
     return False
Exemplo n.º 23
0
 def testFontButtonCallback(self, sender):
     font = CurrentFont()
     if font is None:
         dialogs.message("There is no font to test.",
                         "Open a font and try again.")
         return
     testStates = self._getSettings()
     results = getFontReport(font, testStates, format=True)
     print results
    def open(self):
        if not self.font.info.familyName:
            message("Family Name must be set", full_requirements_message)
            return

        if not self.font.info.openTypeNameDesigner:
            message("Designer must be set", full_requirements_message)
            return

        self.window.open()
    def open(self):
        if not self.font.info.familyName:
            message("Family Name must be set", full_requirements_message)
            return

        if not self.font.info.designer:
            message("Designer must be set", full_requirements_message)
            return

        self.window.open()
Exemplo n.º 26
0
 def getExampleRootPath(self, site):
     view = self.getView()
     root = os.path.expanduser(view.exampleRoot.get()) # File root of server.
     if not root.endswith('/'):
         root += '/'
     if not os.path.exists(root):
         message(messageText='Error in Examples path.', informativeText='The Examples folder "%s" does not exist.' % root, 
             alertStyle=NSInformationalAlertStyle, parentWindow=view)
         return None
     return root + site.getPythonClassName().lower() + '/' 
Exemplo n.º 27
0
 def checkReqVsLen(self, required, maxLength):
     """Check for conflicts between number of required characters and specified word length.
     Only implemented for text input for now.
     """
     if self.matchMode != "grep":
         if len(required) > maxLength:
             message(
                 "word-o-mat: Conflict: Required characters exceed maximum word length. Please revise."
             )
             return False
     return True
Exemplo n.º 28
0
 def getMampRootPath(self, site):
     view = self.getView()
     root = os.path.expanduser(view.mampRoot.get())  # File root of server.
     if not root.endswith('/'):
         root += '/'
     if not os.path.exists(root):
         message(messageText='Error in MAMP path.',
                 informativeText='The MAMP folder "%s" does not exist.' %
                 root,
                 alertStyle=NSInformationalAlertStyle,
                 parentWindow=view)
         return None
     return root + site.getPythonClassName().lower() + '/'
Exemplo n.º 29
0
 def checkRE(self):
     """Check if the regular expression entered by the user compiles."""
     if self.matchMode == "grep":
         try:
             self.matchPatternRE = re.compile(self.matchPattern)
             return True
         except re.error:
             self.matchPatternRE = None
             message ("word-o-mat: Could not compile regular expression.")
             return False
     else:
         self.matchPatternRE = None
         return True
Exemplo n.º 30
0
 def checkRE(self):
     """Check if the regular expression entered by the user compiles."""
     if self.matchMode == "grep":
         try:
             self.matchPatternRE = re.compile(self.matchPattern)
             return True
         except re.error:
             self.matchPatternRE = None
             message("word-o-mat: Could not compile regular expression.")
             return False
     else:
         self.matchPatternRE = None
         return True
Exemplo n.º 31
0
    def loadFromTableCallback(self, sender):
        loadingPath = getFile("Select table with linked sidebearings")
        if loadingPath is None:
            return None

        with open(loadingPath[0], 'r') as linksTable:
            rawTable = [item for item in linksTable.readlines()]

        changedItems = []
        toBeLinksList = list(self.selectedFont.glyphOrder)
        for indexRow, eachRow in enumerate(rawTable):
            lft, lftActive, servant, rgtActive, rgt = [
                item.strip() for item in eachRow.split('\t')
            ]
            servantResult = self._isGlyphNameAllowed(servant)
            lftResult = self._isGlyphNameAllowed(lft)
            rgtResult = self._isGlyphNameAllowed(rgt)

            if all([servantResult, lftResult, rgtResult]) is False:
                message(
                    'Line {} contains a mistake'.format(indexRow + 1),
                    'One or more glyphs [lft:<{}> servant:<{}> rgt:<{}>] are not allowed in this font'
                    .format(lft, servant, rgt))
                return None

            if servant in toBeLinksList:
                servantIndex = toBeLinksList.index(servant)
                toBeLinksList[servantIndex] = {
                    'lft': lft,
                    'lftActive': True if lftActive == 'True' else False,
                    'servant': servant,
                    'rgt': rgt,
                    'rgtActive': True if rgtActive == 'True' else False
                }
                changedItems.append(servantIndex)

        for eachUnchangedIndex in [
                ii for ii in range(len(toBeLinksList))
                if ii not in changedItems
        ]:
            toBeLinksList[eachUnchangedIndex] = {
                'lft': '',
                'lftActive': False,
                'servant': toBeLinksList[eachUnchangedIndex],
                'rgt': '',
                'rgtActive': False
            }

        self.w.linksList.set(toBeLinksList)
        self._compareLibsToList()
Exemplo n.º 32
0
 def convertButtonCallback(self, sender):
     if self.chosenMode == 'Single File':
         inputPath = getFile('Choose the file to convert')[0]
         if inputPath.endswith('.vfb') or inputPath.endswith('.ufo'):
             executeCommand(['vfb2ufo', '-fo', inputPath], shell=True)
         else:
             message('input file path is not correct')
     else:
         inputFolder = getFolder('Choose a folder with files to convert')[0]
         if inputFolder:
             for eachPath in catchFilesAndFolders(inputFolder,
                                                  self.chosenSuffix):
                 executeCommand(['vfb2ufo', '-fo', eachPath], shell=True)
         else:
             message('input folder path is not correct')
Exemplo n.º 33
0
 def _segmentedButton_callback(self, sender):
     sel = sender.get()
     if not sel:
         self.w.df.show(1)
         self.w.rv.show(0)
         self.w.c.show(0)
     elif sel == 1:
         self.w.df.show(0)
         self.w.rv.show(1)
         self.w.c.show(0)
     else:
         self.w.df.show(0)
         self.w.rv.show(0)
         self.w.c.show(1)
         message("Work in Progress...")
Exemplo n.º 34
0
 def checkReqVsFont(self, required, limitTo, fontChars, customCharset):
     """Check if a char is required from a font/selection/mark color that doesn't have it."""
     if limitTo == False:
         return True
     else:
         if len(customCharset) > 0:
             useCharset = customCharset
             messageCharset = "selection of glyphs you would like me to use"
         else:
             useCharset = fontChars
             messageCharset = "font"
         for c in required:
             if not c in useCharset:
                 message ("word-o-mat: Conflict: Character \"%s\" was specified as required, but not found in the %s." % (c, messageCharset))
                 return False
         return True
Exemplo n.º 35
0
    def __init__(self):

        self.font = CurrentFont()
        self.mark = 0

        if not self.font:
            message('Open a font first!')
            return
        # window and UI
        self.w = Window((250, 500), "Groups To Selection",
                        minSize=(250, 200),
                        maxSize=(250, 1000))
        # font groups
        self.w.groupsList = List((10, 10, -10, -70),
                                 [],
                                 columnDescriptions=[
                                     {'title': 'sel', 'editable': True, 'cell': CheckBoxListCell(), 'width': 20},
                                     {'title': 'Group Name'}],
                                 doubleClickCallback=self.doubleClickCallback
                                 )
        self.buildGroupsList(self.font)
        # select/unselect all glyphs in font
        self.w.resetButton = Button((10, -60, -120, 20),
                                    '(un)Select All',
                                    sizeStyle='mini',
                                    callback=self.selectAllCallback)
        # mark and color selection
        self.w.markCheckbox = CheckBox((160, -60, -10, 20),
                                       'mark',
                                       value=self.mark,
                                       sizeStyle='small',
                                       callback=self.markCallback)
        self.w.markColor = ColorWell((210, -60, -10, 20))
        self.w.markColor.enable(False)
        self.w.markColor.set(NSColor.redColor())
        # select
        self.w.makeSelection = Button((10, -30, -10, 20),
                                      "Make Selection",
                                      # minSize=(150, 150),
                                      callback=self.makeSelectionCallback)
        # removeObserver if the window closes
        self.w.bind("close", self.windowCloseCallback)
        self.w.open()

        addObserver(self, "updateCurrentFontCallback", "fontBecameCurrent")
    def send(self, sender):
        recipients = ', '.join(self.window.recipients.get())

        progress = ProgressWindow('', tickCount=3, parentWindow=self.window)

        try:
            tmpdir = tempfile.mkdtemp(prefix="ghostlines")

            progress.update('Generating OTF')

            # Should be controlled which options are used somewhere
            filename = os.path.join(tmpdir, self.font.info.familyName + '.otf')

            self.font.generate(filename, "otf", decompose=True, checkOutlines=True, autohint=True)

            progress.update('Sending via Ghostlines')

            with open(filename, 'rb') as otf:
                params = dict(
                    otf=otf,
                    recipients=recipients,
                    notes=self.window.notes_field.get(),
                    designer_email_address=self.window.email_address_field.get()
                )

                license_path = self.license_storage.retrieve()

                if license_path is not '' and os.path.exists(license_path):
                    with open(license_path, 'rb') as license:
                        filename = os.path.basename(license_path)
                        _, extension = os.path.splitext(license_path)
                        content_type = filetypes[extension]
                        params['license'] = (filename, license, content_type)
                        response = Ghostlines('v0.1').send(**params)
                else:
                    response = Ghostlines('v0.1').send(**params)

            if response.status_code == requests.codes.created:
                message("{} was delivered".format(self.font.info.familyName))
            else:
                print repr(response)
                message("{} could not be delivered".format(self.font.info.familyName),
                        "Error code: {}\n{}".format(response.status_code, response.json()))
        finally:
            progress.close()
Exemplo n.º 37
0
 def checkReqVsFont(self, required, limitTo, fontChars, customCharset):
     """Check if a char is required from a font/selection/mark color that doesn't have it."""
     if limitTo == False:
         return True
     else:
         if len(customCharset) > 0:
             useCharset = customCharset
             messageCharset = "selection of glyphs you would like me to use"
         else:
             useCharset = fontChars
             messageCharset = "font"
         for c in required:
             if not c in useCharset:
                 message(
                     "word-o-mat: Conflict: Character \"%s\" was specified as required, but not found in the %s."
                     % (c, messageCharset))
                 return False
         return True
    def dispatch(self, sender):
        token = AppStorage("accessToken").retrieve()
        font_family_id = self.font_family_id_storage.retrieve(default=None)

        if font_family_id is not None and token is not None and token is not '':
            window = self.window.window().getNSWindow()
            mouseDown = window.mouseLocationOutsideOfEventStream()
            height = self.content_view.frame().size.height
            rect = (mouseDown.x, height - 1, 1, 1)
            headers = {'Authorization': 'Bearer {}'.format(token)}

            self.popover.open(preferredEdge="top", relativeRect=rect)

            if not self.popover.web.url:
                comment_ui_url ="{}/ui/font_families/{}/comments".format(env.api_url, font_family_id)
                self.popover.web.load(comment_ui_url, headers)
        else:
            message("You must register a font first", "Click on the Ghostlines menu item to create a record for this font on Ghostlines. You will then be able to view the comments from all of your releases by clicking this icon.")
Exemplo n.º 39
0
    def getInputString(self, field, stripColon):
        """Read an input string from a field, and convert it to a list of glyphnames."""
        inputString = field.get()
        pattern = re.compile(" *, *| +")
        if stripColon:
            i = inputString.find(":")
            if i != -1:
                inputString = inputString[i+1:]
        result1 = pattern.split(inputString)

        result2 = []
        for c in result1:
            if len(c)>1: # glyph names
                if self.f is not None:
                    if self.f.has_key(c):
                        g = self.f[c]
                        try:
                            value = unicode(unichr(int(g.unicode)))
                            result2.append(value)
                        except TypeError: # unicode not set
                            message ("word-o-mat: Glyph \"%s\" was found, but does not appear to have a Unicode value set. It can therefore not be processed, and will be skipped." % c)
                    else:
                        message ("word-o-mat: Conflict: Character \"%s\" was specified as required, but not found. It will be skipped." % c)
                else:
                        message ("word-o-mat: Sorry, matching by glyph name is only supported when a font is open. Character \"%s\" will be skipped." % c)
            else: # character values
                result2.append(c)
        result = [unicode(s) for s in result2 if s]
        return result
Exemplo n.º 40
0
    def getInputString(self, field, stripColon):
        """Read an input string from a field, and convert it to a list of glyphnames."""
        inputString = field.get()
        pattern = re.compile(" *, *| +")
        if stripColon:
            i = inputString.find(":")
            if i != -1:
                inputString = inputString[i + 1:]
        result1 = pattern.split(inputString)

        result2 = []
        for c in result1:
            if len(c) > 1:  # glyph names
                if self.f is not None:
                    if self.f.has_key(c):
                        g = self.f[c]
                        try:
                            value = str(chr(int(g.unicode)))
                            result2.append(value)
                        except TypeError:  # unicode not set
                            message(
                                "word-o-mat: Glyph \"%s\" was found, but does not appear to have a Unicode value set. It can therefore not be processed, and will be skipped."
                                % c)
                    else:
                        message(
                            "word-o-mat: Conflict: Character \"%s\" was specified as required, but not found. It will be skipped."
                            % c)
                else:
                    message(
                        "word-o-mat: Sorry, matching by glyph name is only supported when a font is open. Character \"%s\" will be skipped."
                        % c)
            else:  # character values
                result2.append(c)
        result = [str(s) for s in result2 if s]
        return result
Exemplo n.º 41
0
    def __init__(self):
        self.font = CurrentFont()
        if self.font is None:
            from vanilla.dialogs import message
            message(
                "No Font is open.",
                "Open or create a font to convert groups to feature syntax groups."
            )
            return

        groupsNames = self.font.groups.keys()
        groupsNames.sort()

        self.w = Window((400, 400),
                        "Feature Group Converter",
                        minSize=(300, 300))

        toolbarItems = [
            dict(
                itemIdentifier="insert",
                label="Insert In Font",
                imageObject=insertFeatureToolbarImage(),
                callback=self.toolbarInsert,
            ),
        ]
        toolbar = self.w.addToolbar(
            toolbarIdentifier="GroupsToFeatureTextToolbar",
            toolbarItems=toolbarItems,
            addStandardItems=False)

        self.w.groupList = List(
            (0, 0, 150, -0),
            groupsNames,
            selectionCallback=self.groupListSelectionCallback)
        self.w.feaText = DoodleFeatureTextEditor((150, 0, -0, -0), "")
        self.w.groupList.setSelection([])

        self.w.assignToDocument(self.font.document())

        self.w.open()
Exemplo n.º 42
0
def logToFile(fontState, infoNoteContent):
    directory, filename, extension = explodePath(fontState.fullPath)
    logFileName = "%schangelog.md" % fontState.basename[:-1]
    logPath = os.path.join(directory,logFileName)
    if (os.path.exists(logPath)):
        with codecs.open(logPath, 'r', 'utf-8') as f:
            logContent = f.read()
    else:
        logContent = u""
    
    newLogContent = time.strftime("### %d.%m.%Y (%H:%M)  \n")
    newLogContent += "**%s%s**  \n" % (filename, extension)
    newLogContent += "version: 0.%03d  \n" % fontState.versionMinor
    newLogContent += "  \n"
    newLogContent += infoNoteContent + "  \n"
    newLogContent += u"\n---------------------------\n"

    logContent = newLogContent + logContent

    with codecs.open(logPath, 'w', 'utf-8') as f:
        f.write(logContent)

    message("operation completed\n" + newLogContent)
Exemplo n.º 43
0
    def writeButtonCallback(self, sender):

        if self.lowerExtreme is not None and self.higherExtreme is not None:

            for eachFont in AllFonts():
                if self.is_hhea is True:
                    eachFont.info.openTypeHheaAscender = self.higherExtreme.y
                    eachFont.info.openTypeHheaDescender = self.lowerExtreme.y

                if self.is_vhea is True:
                    eachFont.info.openTypeVheaVertTypoAscender = self.higherExtreme.y
                    eachFont.info.openTypeVheaVertTypoDescender = self.lowerExtreme.y

                if self.is_osTwo is True:
                    eachFont.info.openTypeOS2TypoAscender = self.higherExtreme.y
                    eachFont.info.openTypeOS2TypoDescender = self.lowerExtreme.y

                if self.is_usWin is True:
                    eachFont.info.openTypeOS2WinAscent = self.higherExtreme.y
                    eachFont.info.openTypeOS2WinDescent = self.lowerExtreme.y

        else:
            message('Calc Extremes first!')
Exemplo n.º 44
0
def downloadCurrentVersion():
    """
    Download the current version (dmg) and mount it
    """
    path = "https://static.typemytype.com/drawBot/DrawBot.dmg"
    try:
        # download and mount
        cmds = ["hdiutil", "attach", "-plist", path]
        popen = subprocess.Popen(cmds,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        out, err = popen.communicate()
        if popen.returncode != 0:
            raise DrawBotError("Mounting failed")
        output = plistlib.loads(out)
        dmgPath = None
        for item in output["system-entities"]:
            if "mount-point" in item:
                dmgPath = item["mount-point"]
                break
        AppKit.NSWorkspace.sharedWorkspace().openFile_(dmgPath)
    except Exception:
        exc = traceback.format_exc()
        message("Something went wrong while downloading %s" % path, exc)
Exemplo n.º 45
0
    def openSelectedComponent(self, f, g):
        selectedComponents = [c for c in g.components if c.selected]

        if not len(selectedComponents):
            message("There is no selected components")
            return

        selectedComponent = selectedComponents[0]
        self.selectedComponentName = selectedComponent.baseGlyph
        self.selectedComponentOffset = selectedComponent.transformation[-2:]
        
        self.oldGlyph = g

        OpenGlyphWindow(f[self.selectedComponentName])

        self.currentGlyph = CurrentGlyph()

        addObserver(self, "currentGlyphChanged", "currentGlyphChanged")
        addObserver(self, "draw", "draw")
        addObserver(self, "draw", "drawPreview")
        addObserver(self, "draw", "drawInactive")
        addObserver(self, "mouseDown", "mouseDown")

        UpdateCurrentGlyphView()
Exemplo n.º 46
0
    def __init__(self):
        if AllFonts() is None:
            from vanilla.dialogs import message
            message("No fonts open.", "Open or create a font to copy data to and fro.")
            return

        self.sourceFontList = AllFonts()
        self.destinationFontList = AllFonts()
        self.source_font = self.sourceFontList[0]
        self.destination_fonts = None
        self.groups = None
        self.kerning = None

        ## create a window
        self.w = Window((400, 500), "Copy Groups and Kerning", minSize=(500, 600))
        self.w.sourceTitle = TextBox((15, 20, 200, 20), "Source Font:")
        self.w.sourceFont = PopUpButton((15, 42, 340, 20), [f.info.familyName + ' ' + f.info.styleName for f in self.sourceFontList], callback=self.sourceCallback)
        self.w.desTitle = TextBox((15, 76, 200, 20), "Destination Fonts:")
        self.w.destinationFonts = FontList((15, 96, -15, -115), self.destinationFontList, selectionCallback=self.desCallback)
        self.w.copyButton = Button((-215, -40, 200, 20), 'Copy Groups & Kerning', callback=self.copyCallback)
        self.w.line = HorizontalLine((10, -60, -10, 1))
        self._updateDest()
        ## open the window
        self.w.open()
Exemplo n.º 47
0
    def _selection2DeepCompo_Button_Callback(self, sender):
        if not self.ui.selectedCompositionGlyphName:
            message("Warning, there is no selected composition glyph name")
            return

        if self.ui.glyph is None:
            message("Warning, there is no glyph")
            return

        selectedContours = [
            c for c in self.ui.glyph
            if c.selected or [p for p in c.points if p.selected]
        ]

        if not selectedContours:
            message("Warning, there is no selectedContours")
            return

        Select2DeepCompoSheet(self.ui, self,
                              self.ui.selectedCompositionGlyphName["Name"],
                              selectedContours)
Exemplo n.º 48
0
 def isInGitRepository(self):
     # Check if the folder is a git repository
     if not os.path.exists(os.path.join(self._path, ".git")):
         message('Warning: this is not a GIT repository')
         return False
     return True
Exemplo n.º 49
0
 def _textCenter_callback(self, sender):
     if not self.font: 
         message("Warning there is no current font")
         return
     from interface.TextCenter import TextCenter
     TextCenter(self)  
Exemplo n.º 50
0
    def makeWords(self, sender=None):
        """Parse user input, save new values to prefs, compile and display the resulting words.

        I think this function is too long and bloated, it should be taken apart. ########
        """

        global warned
        self.f = CurrentFont()

        if self.f is not None:
            self.fontChars, self.glyphNames = self.fontCharacters(self.f)
            self.glyphNamesForValues = {self.fontChars[i]: self.glyphNames[i] for i in range(len(self.fontChars))}
        else:
            self.fontChars = []
            self.glyphNames = []

        self.wordCount = self.getIntegerValue(self.g1.wordCount)
        self.minLength = self.getIntegerValue(self.g1.minLength)
        self.maxLength = self.getIntegerValue(self.g1.maxLength)
        self.case = self.g1.case.get()
        self.customCharset = []

        charset = self.g1.base.get()
        self.limitToCharset = True
        if charset == 0:
            self.limitToCharset = False

        elif charset == 2: # use selection
            if len(self.f.selection) == 0: # nothing selected
                message("word-o-mat: No glyphs were selected in the font window. Will use any characters available in the current font.")
                self.g1.base.set(1) # use font chars
            else:
                try:
                    self.customCharset = []
                    for gname in self.f.selection:
                        if self.f[gname].unicode is not None:
                            try:
                                self.customCharset.append(unichr(int(self.f[gname].unicode)))
                            except ValueError:
                                pass
                except AttributeError:
                    pass

        elif charset == 3: # use mark color
            c = self.g1.colorWell.get()

            if c is None:
                pass
            elif c.className() == "NSCachedWhiteColor": # not set, corresponds to mark color set to None
                c = None

            self.customCharset = []
            self.reqMarkColor = (c.redComponent(), c.greenComponent(), c.blueComponent(), c.alphaComponent()) if c is not None else None
            for g in self.f:
                if g.mark == self.reqMarkColor:
                    try:
                        self.customCharset.append(unichr(int(g.unicode)))
                    except:
                        pass
            if len(self.customCharset) == 0:
                message("word-o-mat: Found no glyphs that match the specified mark color. Will use any characters available in the current font.")
                self.g1.base.set(1) # use font chars
                self.toggleColorSwatch(0)

        self.matchMode = "text" if self.g2.matchMode.get() == 0 else "grep" # braucht es diese zeile noch?

        self.requiredLetters = self.getInputString(self.g2.textMode.mustLettersBox, False)
        self.requiredGroups[0] = self.getInputString(self.g2.textMode.group1box, True)
        self.requiredGroups[1] = self.getInputString(self.g2.textMode.group2box, True)
        self.requiredGroups[2] = self.getInputString(self.g2.textMode.group3box, True)
        self.matchPattern = self.g2.grepMode.grepBox.get()

        self.banRepetitions = self.g3.checkbox0.get()
        self.outputWords = [] # initialize/empty

        self.source = self.g1.source.get()
        languageCount = len(self.textfiles)
        if self.source == languageCount: # User Dictionary
            self.allWords = self.dictWords["user"]
        elif self.source == languageCount+1: # Use all languages
            for i in range(languageCount):
                # if any language: concatenate all the wordlists
                self.allWords.extend(self.dictWords[self.textfiles[i]])
        elif self.source == languageCount+2: # Custom word list
            try:
                if self.customWords != []:
                    self.allWords = self.customWords
                else:
                    self.allWords = self.dictWords["ukacd"]
                    self.g1.source.set(0)
            except AttributeError:
                self.allWords = self.dictWords["ukacd"]
                self.g1.source.set(0)
        else: # language lists
            for i in range(languageCount):
                if self.source == i:
                    self.allWords = self.dictWords[self.textfiles[i]]

        # store new values as defaults

        markColorPref = self.reqMarkColor if self.reqMarkColor is not None else "None"

        extDefaults = {
            "wordCount": self.wordCount,
            "minLength": self.minLength,
            "maxLength": self.maxLength,
            "case": self.case,
            "limitToCharset": self.writeExtDefaultBoolean(self.limitToCharset),
            "source": self.source,
            "matchMode": self.matchMode,
            "matchPattern": self.matchPattern, # non compiled string
            "markColor": markColorPref,
            }
        for key, value in extDefaults.items():
            setExtensionDefault("com.ninastoessinger.word-o-mat."+key, value)

        # go make words
        if self.checkInput(self.limitToCharset, self.fontChars, self.customCharset, self.requiredLetters, self.minLength, self.maxLength, self.case) == True:

            checker = wordcheck.wordChecker(self.limitToCharset, self.fontChars, self.customCharset, self.requiredLetters, self.requiredGroups, self.matchPatternRE, self.banRepetitions, self.minLength, self.maxLength, matchMode=self.matchMode)

            for i in self.allWords:
                if len(self.outputWords) >= self.wordCount:
                    break
                else:
                    w = choice(self.allWords)
                    if self.case == 1:   w = w.lower()
                    elif self.case == 2:
                        # special capitalization rules for Dutch IJ
                        # this only works when Dutch is selected as language, not "any".
                        try:
                            ijs = ["ij", "IJ", "Ij"]
                            if self.languageNames[self.source] == "Dutch" and w[:2] in ijs:
                                wNew = "IJ" + w[2:]
                                w = wNew
                            else:
                                w = w.title()
                        except IndexError:
                            w = w.title()
                    elif self.case == 3:
                        # special capitalization rules for German double s
                        if u"ß" in w:
                            w2 = w.replace(u"ß", "ss")
                            w = w2
                        w = w.upper()

                    if checker.checkWord(w, self.outputWords):
                        self.outputWords.append(w)

            # output
            if len(self.outputWords) < 1:
                message("word-o-mat: no matching words found <sad trombone>")
            else:
                joinString = " "
                if self.g3.listOutput.get() == True:
                    joinString = "\\n"
                    self.outputWords = self.sortWordsByWidth(self.outputWords)
                outputString = joinString.join(self.outputWords)
                try:
                    sp = OpenSpaceCenter(CurrentFont())
                    sp.setRaw(outputString)
                except:
                    if warned == False:
                        message("word-o-mat: No open fonts found; words will be displayed in the Output Window.")
                    warned = True
                    print("word-o-mat: %s" % outputString)
        else:
            print("word-o-mat: Aborted because of errors")
Exemplo n.º 51
0
 def checkMinVsMax(self, minLength, maxLength):
     """Check user input for minimal/maximal word length and see if it makes sense."""
     if not minLength <= maxLength:
         message ("word-o-mat: Confusing input for minimal/maximal word length. Please fix.")
         return False
     return True
Exemplo n.º 52
0
import os
from vanilla.dialogs import message
from replicant.helpers import createArchiveYesNo
from replicant.models import Replicant

replicant = Replicant(CurrentFont())
if not replicant.font:
    message("No open font", "You must have an open, saved font to replicate.")
elif os.path.exists(replicant.path) or createArchiveYesNo():
    replicant.replicate()
    def __init__(self):

        self.font = CurrentFont()
        if self.font is None:
            from vanilla.dialogs import message
            message("Oops!", "You need a font to use this tool.")
            return

        x = 10
        y = 10
        h = 40
        w = -10

        layers = self.font.layerOrder
        if len(layers) < 1:
            from vanilla.dialogs import message
            message("Oops!", "You need two layers to use this tool.")
            return

        lh = len(layers)*20+20

        self.layerName = layers[0]
        self.currentPen = None

        self.w = FloatingWindow((200, 330), "Broad Nib Background")


        stepValue = getExtensionDefault("%s.%s" %(BroadNibBackgroundDefaultKey, "step"), 20)
        self.w.step = SliderGroup((x, y, w, h), "Steps:", 0, 60, stepValue, callback=self.stepChanged)

        y+=h

        widthValue = getExtensionDefault("%s.%s" %(BroadNibBackgroundDefaultKey, "width"), 50)
        self.w.width = SliderGroup((x, y, w, h), "Width:", 0, 300, widthValue, callback=self.widthChanged)

        y+=h

        heightValue = getExtensionDefault("%s.%s" %(BroadNibBackgroundDefaultKey, "height"), 10)
        self.w.height = SliderGroup((x, y, w, h), "Height:", 0, 300, heightValue, callback=self.heightChanged)

        y+=h

        angleValue = getExtensionDefault("%s.%s" %(BroadNibBackgroundDefaultKey, "angle"), 30)
        self.w.angle = SliderGroup((x, y, w, h), "Angle:", 0, 360, angleValue, callback=self.angleChanged)
        self.w.angle.slider.getNSSlider().cell().setSliderType_(NSCircularSlider)
        self.w.angle.text.setPosSize((0, 15, -0, 20))
        self.w.angle.slider.setPosSize((60, 10, 30, 30))
        self.w.angle.slider._nsObject.cell().setControlSize_(NSRegularControlSize)

        y+=h + 20

        shapeValue = getExtensionDefault("%s.%s" %(BroadNibBackgroundDefaultKey, "shape"), 0)
        self.w.shapetext = TextBox((x, y, -0, 20), "Shape:")
        self.w.shape = RadioGroup((74, y, -0, 20), ["oval", "rect"], isVertical=False, callback=self.shapeChanged)
        self.w.shape.set(shapeValue)

        y+=h + 5

        color = NSColor.colorWithCalibratedRed_green_blue_alpha_(1, 0, 0, .5)
        colorValue = getExtensionDefaultColor("%s.%s" %(BroadNibBackgroundDefaultKey, "color"), color)
        self.w.colortext = TextBox((x, y, -0, 20), "Color:")
        self.w.color = ColorWell((70, y-5, w, 30), callback=self.colorChanged, color=colorValue)

        y+=h + 20

        self.w.layertext = TextBox((x, y-20, -0, 20), "Layer:")
        self.w.layer = List((x, y, w, lh), layers, allowsMultipleSelection=False, selectionCallback=self.layerChanged)

        y+=lh+15

        self.w.setPosSize((100, 100, 200, y))

        addObserver(self, "drawBroadNibBackground", "drawBackground")

        # needed for windowCloseCallback
        self.setUpBaseWindowBehavior()

        self.w.open()