示例#1
0
def getVarFontInstance(fontOrPath,
                       location,
                       styleName=None,
                       normalize=True,
                       cached=True,
                       lazy=True):
    """The getVarFontInstance refers to the file of the source variable font.
    The nLocation is dictionary axis locations of the instance with values between (0, 1000), e.g.
    dict(wght=0, wdth=1000) or values between  (0, 1), e.g. dict(wght=0.2, wdth=0.6).
    Set normalize to False if the values in location already are matching the axis min/max of the font.
    If there is a [opsz] Optical Size value defined, then store that information in the font.info.opticalSize.
    The optional *styleName* overwrites the *font.info.styleName* of the *ttFont* or the automatic
    location name."""
    if isinstance(fontOrPath, str):
        varFont = getFont(fontOrPath, lazy=lazy)
    else:
        varFont = fontOrPath
    if varFont is None:  # Could not read the Variable Font on that path.
        return None
    path = generateInstance(varFont.path,
                            location,
                            targetDirectory=getInstancePath(),
                            normalize=normalize,
                            cached=cached,
                            lazy=lazy)
    # Answer the generated Variable Font instance. Add [opsz] value if is defined in the location, otherwise None.
    instance = getFont(path, lazy=lazy)
    instance.info.opticalSize = location.get('opsz')
    instance.info.location = location
    instance.info.varStyleName = styleName
    return instance
示例#2
0
文件: family.py 项目: jkim828/PageBot
def getFamilyPaths(useFontInfo=True, useFileName=True, force=False):
    """Construct a dictionary of familyName-->[fontPath, fontPath, ...]. If
    omitted, then create the families from all avaible font paths found by the
    context.

    The flag useFontInfo defines if the familyName, styleName) should be taken
    from the font.info or just guessed from the font file name.

    >>> familyPaths = getFamilyPaths()
    >>> len(familyPaths['Roboto'])
    38
    >>> len(familyPaths['Bungee'])
    5
    """
    global FAMILY_PATHS
    if force:
        FAMILY_PATHS = {}
    if not FAMILY_PATHS:  # If forced or not initialized yet
        for fontPath in getFontPaths().values():
            familyName = None
            if useFontInfo:
                font = getFont(fontPath)
                if font is not None:
                    familyName = font.info.familyName

            if not familyName and useFileName:
                familyName = path2FamilyName(fontPath)

            if familyName is not None:
                if familyName not in FAMILY_PATHS:
                    FAMILY_PATHS[familyName] = []
                FAMILY_PATHS[familyName].append(fontPath)
    return FAMILY_PATHS
示例#3
0
 def addFont(self, fontOrPath):
     """Add the fonts to the family. This can be a list of Font instances, a
     list of font names or a list of font paths."""
     """
     FIXME: restore doctests.
     >>> from pagebot.fonttoolbox.objects.font import findFont
     >>> font = findFont('Roboto-Regular')
     >>> path = font.path
     >>> families = getFamilies()
     >>> family = newFamily('MyOtherFamily')
     >>> font = family.addFont(path)
     >>> font.path == path
     True
     >>> len(family)
     1
     """
     font = None
     if isinstance(fontOrPath, self.FONT_CLASS):
         self.fonts[fontOrPath.path] = font = fontOrPath
     elif os.path.isdir(fontOrPath):
         for fileName in os.listdir(fontOrPath):
             if not fontOrPath.endswith('/'):
                 fontOrPath += '/'
             filePath = fontOrPath + fileName
             if not filePath in self.fonts:  # Only create if not already there.
                 font = getFont(filePath)
                 if font is not None:
                     self.fonts[
                         filePath] = font  # Not recursive, this just folder.
             else:  # Font exists, just return it
                 font = self.fonts[filePath]
     else:
         font = getFont(fontOrPath)
         if font is not None:
             self.fonts[fontOrPath] = font
     return font
示例#4
0
def getFamilies(familyPaths=None,
                useFontInfo=True,
                useFileName=True,
                force=False):
    u"""Construct a dictionary of Family instances from dictionary familyPaths. If omitted, then create
    the families from all aviable font paths found in the by the context.
    The flag useFontInfo defines if the familyName, styleName) should be taken from the font.info
    or guess from the font file name.

    >>> families = getFamilies()
    >>> 'Roboto' in families
    True
    >>> 'Bungee' in families
    True
    >>> families = getFamilies(useFontInfo=False, force=True) # Forced to look an fileName only, Roboto is a family
    >>> 'Roboto' in families
    True
    >>> families = getFamilies(useFileName=False, force=True) # Looking into font.info, Roboto is the family name.
    >>> 'Roboto' in families
    True
    >>> #families = getFamilies(useFontInfo=False, useFileName=False) finds nothing
    """
    global FAMILIES
    if force:
        FAMILIES = {}
    if not FAMILIES:  # If forced or not initialized yet
        for fontPath in getFontPaths().values():
            font = getFont(fontPath)
            if font is not None:
                #print(font.path.split('/')[-1], repr(font.info.familyName), repr(font.info.styleName))
                familyName = None
                if useFontInfo:
                    familyName = font.info.familyName
                if not familyName and useFileName:
                    familyName = path2FamilyName(font.path)
                if familyName:
                    if familyName not in FAMILIES:
                        FAMILIES[familyName] = Family(familyName)
                    FAMILIES[familyName].addFont(font)
    return FAMILIES
示例#5
0
    def fitString(cls,
                  t,
                  context,
                  e=None,
                  style=None,
                  w=None,
                  h=None,
                  useXTRA=True,
                  pixelFit=True):
        u"""Answer the DrawBotString instance from valid attributes in style. Set all values after testing
        their existence, so they can inherit from previous style formats in the string.
        If the target width w and height are defined, and if there is a [wdth] or [XTRA] axis in the
        current Variable Font, then values are iterated to make the best location/instance for the
        rectangle fit.
        In case the fontSize is set and the width w is set, then just use the [wdth] or [XTRA] to 
        make a horizontal fit, keeping the size. If the axes run to extreme, the string is return 
        without changing width.
        In case the a font path was supplied, then try to get a Font instance for that path, as we
        need to test it for existing axes as Variable Font.

        >>> from pagebot.contexts.drawbotcontext import DrawBotContext
        >>> context = DrawBotContext()
        >>> from pagebot.fonttoolbox.objects.font import findFont
        >>> #font = findFont('RobotoDelta-VF')
        >>> font = findFont('Fit-Variable_1')        
        >>> style = dict(font=font)
        >>> 'wdth' in font.axes.keys() or 'XTRA' in font.axes.keys() # One of them is there
        True
        >>> s = DrawBotString.newString('Hello', context, style=style, w=300)
        >>> int(round(s.bounds()[2])), int(round(s.fittingFontSize)) # Rounded width
        (297, 195)
        >>> s = DrawBotString.fitString('Hello', context, style=style, w=400, h=220)
        >>> int(round(s.bounds()[2]-s.bounds()[0])) # Rounded pixel width
        399
        >>> int(round(s.bounds()[3]-s.bounds()[1])) # Rounded pixel height
        220
        >>> #s.bounds()

        """
        style = copy(style)
        location = copy(css(
            '', e, style,
            {}))  # In case the used already supplied a VF location, use it.
        font = css('font', e, style)
        if isinstance(font,
                      str):  # Assuming it's a path, get the Font instance.
            font = getFont(font)  # Make sure we gave a real Font instance.
        style['font'] = font
        # Get the flag if fit locations should be rounded (less cached instance) or accurate.
        roundVariableFitLocation = style.get('roundVariableFitLocation', True)
        # In case font is not a variable font, or not [wdth] or [XTRA] present, then using normal
        # string fit is the best we can do.
        if not 'wdth' in font.axes and not 'XTRA' in font.axes:
            return cls.newString(t,
                                 context,
                                 e=e,
                                 style=style,
                                 w=w,
                                 h=h,
                                 pixelFit=pixelFit)

        # Decide which axis to use for width adjustments and get the axis values.
        if not useXTRA or not 'XTRA' in font.axes:  # Try to force usage of [XTRA] if it exists, otherwise use[wdth]
            axisTag = 'wdth'
        else:
            axisTag = 'XTRA'
        minValue, defaultValue, maxValue = font.axes[axisTag]
        #print(0, minValue, defaultValue, maxValue )
        if h is not None:  # Fitting in heigt, calculate/iterate for the fitting font size.
            bs = cls.newString(t,
                               context,
                               e=e,
                               style=style,
                               h=h,
                               pixelFit=pixelFit)
            style['fontSize'] = bs.fittingFontSize
        else:  # Assuming there is a fontSize set, we'll use that as vertical requirement
            bs = cls.newString(t, context, e=e, style=style, pixelFit=pixelFit)

        # Now we have a formatted string with a given fontSize, guess to fit on the width.
        tx, _, tw, _ = bs.bounds()  # Get pixel bounds of the string
        tw = tw - tx  # Pixel width of the current string.
        #print(0, tw, w, h)
        prevW = None  # Testing if something changed, for extreme of axes.
        axisValue = defaultValue

        for n in range(
                100):  # Limit the maximum amount of iterations as safeguard
            if tw > w:  # Too wide, try iterate smaller in ratio of wdth/XTRA axis values
                #print(1, tw, w)
                maxValue = axisValue  # Clip wide range to current
                # Guess the new axisvalue from the ratio of tw/w
                axisValue = (axisValue - minValue) / 2 + minValue
                if roundVariableFitLocation:
                    axisValue = int(round(axisValue))
                #print(2, axisValue, minValue, defaultValue, maxValue)
                loc = copy(location)
                loc[axisTag] = axisValue
                loc['opsz'] = int(style['fontSize'])
                #print(3, loc, font.axes.keys())
                style['font'] = getInstance(font, loc)
                bs = cls.newString(t,
                                   context,
                                   e=e,
                                   style=style,
                                   pixelFit=pixelFit)
                tx, ty, tw, th = bs.bounds()  # Get pixel bounds of the string
                tw = tw - tx  # Total width for the current
                #print(5, tw, w, th-ty, h)
                if prevW == tw:  # Did not change, probably not able to get more condensed
                    break
                prevW = tw

            elif tw < w - cls.FITTING_TOLERANCE:  # Too condensed, try to make wider.
                #print(11, tw, w)
                minValue = axisValue  # Clip narrow range to current
                axisValue = (maxValue - axisValue) / 2 + axisValue
                if roundVariableFitLocation:
                    axisValue = int(round(axisValue))
                loc = copy(location)
                loc[axisTag] = axisValue
                loc['opsz'] = int(style['fontSize'])
                style['font'] = getInstance(font, loc)
                bs = cls.newString(t,
                                   context,
                                   e=e,
                                   style=style,
                                   pixelFit=pixelFit)
                tx, ty, tw, th = bs.bounds()  # Get pixel bounds of the string
                tw = tw - tx  # Total width for the current
                #print(15, tw, w, th-ty, h)
                if prevW == tw:  # Did not change, probably not able to get more condensed
                    break
                prevW = tw

            else:  # We found a fitting VF-location within tolerance. Back out.
                break
        #print('Number of iterations', n)
        return bs
示例#6
0
                if context.onBlack((x, y), path) and (not context.onBlack(
                    (x + grid, y), path) or not context.onBlack(
                        (x + grid, y - grid), path)):
                    context.fill(0)
                    context.oval(pt(x - r / 2), pt(y - r / 2), r, r)

    context.stroke((1, 0, 0))
    context.fill(noColor)
    context.drawPath(path)
    context.stroke((0, 1, 0), 5)
    context.rect(e.x, e.y, e.w, e.h)


fontPath = getTestFontsPath() + '/djr/bungee/Bungee-Regular.ttf'
font = getFont(fontPath)
glyphName = 'e'  #'cid05405.1'

doc = Document(w=W, h=H, originTop=False, autoPages=1)

view = doc.getView()
view.padding = 40  # Aboid showing of crop marks, etc.
view.showCropMarks = True
view.showRegistrationMarks = True
view.showFrame = True
view.showOrigin = True
view.showDimensions = False
view.showFrame = True

# Get list of pages with equal y, then equal x.
#page = doc[1][0] # Get the single page from te document.
示例#7
0
print(fontNames)

fontNames = context.installedFonts('Verdana-BoldItalic')
# ['Verdana-BoldItalic']
print(fontNames)

fontNames = context.installedFonts(['Verdana', 'Georgia'])
# ['Georgia', 'Georgia-Bold', 'Georgia-BoldItalic', 'Georgia-Italic', 'Verdana', 'Verdana-Bold', 'Verdana-BoldItalic', 'Verdana-Italic']
print(fontNames)

# The PageBot method to look for fonts is find a fanily with an exact name match
family = getFamily('Bungee')
# <PageBot Family Bungee (5 fonts)>
print(family)

font = getFont('Verdana-BoldItalic')

font = findFont('Roboto')
# None
print(font)

robotoRegular = findFont('Roboto-Regular')
# <Font Roboto-Regular>
print(robotoRegular)

font = findFont('Roboto-cannot-be-found', default='Roboto-Regular')
# <Font Roboto-Regular>
print(font)

font = findFont('Roboto-cannot-be-found', default=robotoRegular)
# <Font Roboto-Regular>