Пример #1
0
    def metadata(self, filename, force=0):
        """Retrieve metadata from font file

        filename -- fully specified path to the font file
        force -- if false, and the metadata is already
        available for this file, do not access the
        font file to retrieve, just return the existing
        metadata.

        return value:
            tuple of:
                filename -- fully specified absolute path
                modifiers -- (weightInteger, italicsFlag)
                specificName -- specific name of the particular
                font stored in the given file, the name of
                the "modified" font
                fontName -- name of the general font which
                the modifiers are specialising
                specifier -- family specifier, two-tuple of
                high-level and sub-level font classifications
                based on font characteristics as encoded
                in the font file.
        """
        filename = os.path.abspath(filename)
        if self.files.has_key(filename) and not force:
            return self.specificFonts.get(self.files[filename])
        font = describe.openFont(filename)
        try:
            modifiers = describe.modifiers(font)
        except (KeyError, AttributeError), err:
            modifiers = (None, None)
Пример #2
0
    def metadata(
        self,
        filename,
        force = 0
    ):
        """Retrieve metadata from font file

        filename -- fully specified path to the font file
        force -- if false, and the metadata is already
        available for this file, do not access the
        font file to retrieve, just return the existing
        metadata.

        return value:
            tuple of:
                filename -- fully specified absolute path
                modifiers -- (weightInteger, italicsFlag)
                specificName -- specific name of the particular
                font stored in the given file, the name of
                the "modified" font
                fontName -- name of the general font which
                the modifiers are specialising
                specifier -- family specifier, two-tuple of
                high-level and sub-level font classifications
                based on font characteristics as encoded
                in the font file.
        """
        filename = os.path.abspath( filename )
        if self.files.has_key( filename ) and not force:
            return self.specificFonts.get( self.files[filename] )
        font = describe.openFont(filename)
        try:
            modifiers = describe.modifiers( font )
        except (KeyError,AttributeError), err:
            modifiers = (None,None)
def buildTable( filenames=None, failureCallback=None ):
	"""Build table mapping {family:(font:{modifiers:(name,file)})}

	filenames -- if provided, list of filenames to scan,
		otherwise the full set of system fonts provided
		by findsystem will be used.
	failureCallback -- if provided, a function taking three
		arguments, the failing filename, an error-type code,
		and the error object.  If processing should stop,
		raise an error.
		codes:
			0 -- couldn't open the font file
			1 -- couldn't find modifiers in the font file
			2 -- couldn't find font-name in the font file
			3 -- couldn't find the generic family specifier
				for the font
	"""
	if filenames is None:
		filenames = findsystem.findFonts()
	table = {}
	for filename in filenames:
		try:
			font = describe.openFont(filename)
		except Exception as err:
			if failureCallback:
				failureCallback( filename, 0, err )
		else:
			try:
				modifiers = describe.modifiers( font )
			except (KeyError,AttributeError) as err:
				if failureCallback:
					failureCallback( filename, 1, err )
				modifiers = (None,None)
			try:
				specificName, fontName = describe.shortName( font )
			except (KeyError,AttributeError) as err:
				if failureCallback:
					failureCallback( filename, 2, err )
			else:
				try:
					specifier = describe.family(font)
				except KeyError:
					if failureCallback:
						failureCallback( filename, 3, err )
				else:
					table.setdefault(
						specifier,
						{}
					).setdefault(
						fontName,
						{}
					)[modifiers] = (specificName,filename)
	return table
Пример #4
0
def buildTable(filenames=None, failureCallback=None):
    """Build table mapping {family:(font:{modifiers:(name,file)})}

    filenames -- if provided, list of filenames to scan,
    otherwise the full set of system fonts provided
    by findsystem will be used.
    failureCallback -- if provided, a function taking three
    arguments, the failing filename, an error-type code,
    and the error object.  If processing should stop,
    raise an error.
    codes:
    
        0 -- couldn't open the font file
        1 -- couldn't find modifiers in the font file
        2 -- couldn't find font-name in the font file
        3 -- couldn't find the generic family specifier
        for the font
    """
    if filenames is None:
        filenames = findsystem.findFonts()
    table = {}
    for filename in filenames:
        try:
            font = describe.openFont(filename)
        except Exception as err:
            if failureCallback:
                failureCallback(filename, 0, err)
        else:
            try:
                modifiers = describe.modifiers(font)
            except (KeyError, AttributeError) as err:
                if failureCallback:
                    failureCallback(filename, 1, err)
                modifiers = (None, None)
            try:
                specificName, fontName = describe.shortName(font)
            except (KeyError, AttributeError) as err:
                if failureCallback:
                    failureCallback(filename, 2, err)
            else:
                try:
                    specifier = describe.family(font)
                except KeyError:
                    if failureCallback:
                        failureCallback(filename, 3, err)
                else:
                    table.setdefault(specifier, {}).setdefault(
                        fontName, {})[modifiers] = (specificName, filename)
    return table
Пример #5
0
def find_font():
  #load fonts
  registry.scan()
  fonts = registry.matchName(args.font)
  if len(fonts)>1:
    print "more than 1 font by that name, aborting"
    for font in fonts:
        print font
    exit(1)

  font_file =registry.fontFile(fonts[0])
  if args.debug:
    print "font found at", font_file

  font = describe.openFont(font_file)
  return font
Пример #6
0
def find_font():
    #load fonts
    registry.scan()
    fonts = registry.matchName(args.font)
    if len(fonts)>1:
        print "more than 1 font by that name, aborting"
        for font in fonts:
                print font
        exit(1)

    font_file =registry.fontFile(fonts[0])
    if args.debug:
        print "font found at", font_file

    font = describe.openFont(font_file)
    return font
Пример #7
0
def load_font(fontname, allow_fallback, ttf_registry=ttffiles.Registry()):
    try:
        return describe.openFont("C:/Windows/Fonts/" + fontname)
    except IOError:
        pass

    try:
        if 0 == len(ttf_registry.fonts):
            ttf_registry.scan()
        return ttf_registry.fontFile(os.path.splitext(fontname)[0])
    except KeyError:
        if allow_fallback:
            print "could not load font", fontname, " so try to fall back to arial"
            return load_font("arial.ttf", False)
        else:
            raise IOError("could not load font", fontname,
                          " and no fallback is allowed->we are done")
Пример #8
0
    def withFont( self, callable, *arguments, **named ):
        """Call a callable while we have a .font attribute

        This method opens the font file and then calls the given
        callable object.  On exit, it eliminates the font.

        XXX Currently this is not reentrant :( 
        """
        if __debug__:
            log.info( """Opening TrueType font %r with fonttools""", self.filename)
        self.font = describe.openFont( self.filename )
        try:
            return callable( *arguments, **named )
        finally:
            try:
                del self.font
            except AttributeError:
                pass
Пример #9
0
    def withFont( self, callable, *arguments, **named ):
        """Call a callable while we have a .font attribute

        This method opens the font file and then calls the given
        callable object.  On exit, it eliminates the font.

        XXX Currently this is not reentrant :( 
        """
        if __debug__:
            log.info( """Opening TrueType font %r with fonttools""", self.filename)
        self.font = describe.openFont( self.filename )
        try:
            return callable( *arguments, **named )
        finally:
            try:
                del self.font
            except AttributeError:
                pass
Пример #10
0
def getImageSizeFor(str):
    fontSize = 10.0
    unitsPerEm = 2048.0
    ppiScale = 96.0 / 72.0
    scalingFactor = fontSize * ppiScale / unitsPerEm
    from ttfquery import describe, glyphquery
    myfont = describe.openFont("C:\\Windows\\Fonts\\arial.ttf")
    width = 0
    widestWidth = getWidestHMetric() * scalingFactor
    for char in str:
        try:
            print "Width of char %s: %f" % (char, (glyphquery.width(myfont, char) * scalingFactor))
            width += glyphquery.width(myfont, char) * scalingFactor
        except:
            print "Exception thrown on", char
            width += widestWidth
        print "Total width:", width
    height = getHeight() * scalingFactor
    return (int(math.ceil(width)), int(math.ceil(height)))
Пример #11
0
def getImageSizeFor(str):
    fontSize = 10.0
    unitsPerEm = 2048.0
    ppiScale = 96.0 / 72.0
    scalingFactor = fontSize * ppiScale / unitsPerEm
    from ttfquery import describe, glyphquery
    myfont = describe.openFont("C:\\Windows\\Fonts\\arial.ttf")
    width = 0
    widestWidth = getWidestHMetric() * scalingFactor
    for char in str:
        try:
            print "Width of char %s: %f" % (char,
                                            (glyphquery.width(myfont, char) *
                                             scalingFactor))
            width += glyphquery.width(myfont, char) * scalingFactor
        except:
            print "Exception thrown on", char
            width += widestWidth
        print "Total width:", width
    height = getHeight() * scalingFactor
    return (int(math.ceil(width)), int(math.ceil(height)))
Пример #12
0
    def print_text(self, text: Tuple[str, str], x_offset, y_offset, scaling):

        curr_offset = 0

        chars = text[0]
        font_file = text[1]

        for char in chars:
            font = describe.openFont(f"fonts/{font_file}.ttf")
            glyph_name = font["cmap"].getBestCmap().get(ord(char))
            g = glyph.Glyph(glyph_name)

            contours = g.calculateContours(font)

            coords_list = []

            largest_point = -10000

            for c in range(len(contours)):
                countour = contours[c]

                curr_coords = []

                for i in range(len(countour)):
                    point = countour[i][0]
                    x = point[0] + curr_offset
                    y = point[1]
                    curr_coords.append([x * 0.05, y * 0.05])

                    if point[0] > largest_point:
                        largest_point = point[0]

                coords_list.append(curr_coords)

            curr_offset += (largest_point + 5)

            self.print_coords(coords_list, x_offset, y_offset, scaling)
Пример #13
0
import numpy as np
from ttfquery import describe
from ttfquery import glyphquery
import matplotlib.pyplot as plt
import matplotlib.cm as cm

to_write = input("Enter a word: \n")
# to_write = "NaTuRaL wRiTiNg"
list_char = list(to_write)
width = 0
angle_threshold = 130 / 180 * np.pi
point_spacing = 100

font_url = "fonts/cnc_v.ttf"
font = describe.openFont(font_url)
# v = 500
timestp = 0.0
space_width = 400
text_size = 1
z_distance = 0.2

amax = 50
vmax = 10


def find_angle(point1, point2, point3):
    a = distance(point1, point2)
    b = distance(point2, point3)
    c = distance(point3, point1)
    angle = np.arccos((a**2 + b**2 - c**2) / (2 * a * b))
    return angle
Пример #14
0
from ttfquery import describe, glyphquery, glyph


# Set font here ----->
f = describe.openFont("/Library/Fonts/Impact.ttf")

# Set character here, in this case its C
n = glyphquery.glyphName(f, 'C')
g = glyph.Glyph(n)
c = g.calculateContours(f)
o = glyph.decomposeOutline(c[1])

# Print out the Polyline
print o
Пример #15
0
import ttfquery.glyph as glyph

import numpy as np
from scipy.interpolate import splprep, splev

import sys

if len(sys.argv) == 1:
    print("usage: python font.py [character]")
    exit(1)

# Open the character given as command line argument
g = glyph.Glyph(sys.argv[1])

# Open our font file
font = describe.openFont("LiberationSans.ttf")

# Get the curves on the font, each contour is an "island" on the glyph
# For example, i has the main stem and the dot on top, which are separate
# contours.
contours = g.calculateContours(font)

for contour in contours:
    x = []
    y = []
    flags = []

    # For each point in the contour add to lists
    for point, flag in contour:
        x.append(point[0])
        y.append(point[1])
Пример #16
0
def text(pos=(0,0), text="", font=None, height=1.0, align='left', spacing=0.03, rotate=0.0,
         scale=1.0, xscale=1.0, yscale=1.0, thickness=None, vertical_spacing=None,
         info=False):
    # If info == True, the caller wants the additional info such as upper-left, etc.
    # In this case we return an instance of the class text_info, with the Polygon as
    # an attribute, text_info.Polygon. The main client of this extra info is the text object.
    if thickness is not None:
        raise AttributeError("Thickness is not allowed in a text shape.")
    if scale != 1.0: xscale = yscale = scale
    lines = text.split('\n')
    while lines[-1] == '\n': # strip off trailing newlines
        lines = lines[:-1]
    if font is None:
        font = "serif"
    font = describe.openFont(findFont(font))
    
    try:
        fonth = glyphquery.charHeight(font)
    except:
        fonth = 1000
    if fonth == 0: fonth = 1000
    
    try:
        desc = glyphquery.charDescent(font) # charDescent may not be present
        fontheight = fonth+desc
        fontscale = 1./fontheight
        descent = fontscale*desc
    except:
        descent = -0.3*height # approximate value
        fontheight = 0.7*fonth
        fontscale = 1.3/fontheight
        
    if vertical_spacing is None:
        vertical_spacing = height*fontscale*glyphquery.lineHeight(font)

    excludef_list = [("ITCEdscr")]
    excludec_list = [("FRSCRIPT", "A"), ("jokerman", "O"),
                    ("vivaldii", "O"), ("vivaldii", "Q"),
                    ("vivaldii", "R")]
    
    ptext = [] 
    widths = []
    width = 0.0
    starts = []
    start = 0.0

    for line in range(len(lines)):
        ptext.append(Polygon())
        bb = 0
        
        for newchar in lines[line]:
            if newchar == " ":
                try:
                    if a:
                        bx = a.boundingBox()
                        bba = bx[1]-bx[0]
                        bba = min(bba, 700)
                        bb += bba
                except:
                    pass
                continue
            n = glyphquery.glyphName(font, newchar)

            if n == ".notdef":
                print("The character '"+newchar+"' is not supported in the font "+font)
                continue
            
            g = glyph.Glyph(n)
            c = g.calculateContours(font)
            contours = []

            for contour in c:
                contours.append(glyph.decomposeOutline(contour))
                if len(contours[-1]) == 0: contours.pop()

            for contour in contours:
                pp = 0
                for i in range(len(contour)-1):
                    if (contour[i][0] == contour[i+1][0]) and (contour[i][1] == contour[i+1][1]):
                        contour.pop(i)
                        pp += 1
                        if i+pp >= len(contour)-1: break

            def lenctr(contour):
                totlen = 0
                for j in range(len(contour)-1):
                    totlen += (vis.vector(contour[j])-vis.vector(contour[j+1])).mag
                return totlen

            lc = len(contours)
            
            if lc >= 4:
                mli = 0
                maxl = 0
                lengths = []
                for i in range(len(contours)):
                    totlen = lenctr(contours[i])
                    lengths.append((totlen,i))
                    if totlen > maxl:
                        mli = i
                        maxl = totlen

                lengths.sort()
                lengths.reverse()
                ocontours = []
                for ll in lengths:
                    ocontours.append(contours[ll[1]])
                contours = ocontours

                indxf = -1
                indxc = -1
                if (mli > 0 and newchar != "%"):
                    try: indxf = excludef_list.index(self.font)
                    except: pass
                    if indxf == -1:
                        try: indxc = excludec_list.index((self.font, newchar))
                        except: pass
                    if (indxf == -1 and indxc == -1):
                        maxc = contours.pop(mli)
                        contours.insert(0, maxc)
                               
            a = Polygon(contours[0])
            for i in range(1,len(contours)):
                b = Polygon(contours[i])
                if a.covers(b): a = a - b
                elif b.covers(a): a = b - a
                else: a = a + b

            a.shift(bb - a.boundingBox()[0] ,0)
           
            ptext[line] += a
            
            bx = ptext[line].boundingBox()
            bb = bx[1] - bx[0] + spacing*fontheight

        newwidth = fontscale*height*(ptext[line].boundingBox()[1]-ptext[line].boundingBox()[0])
        widths.append(newwidth)
        if newwidth > width: width = newwidth
        
        ptext[line].scale(xscale*fontscale*height, yscale*fontscale*height, 0, 0)
        
    for line in range(len(lines)):
        if align == 'left':
            ptext[line].shift(-width/2,-line*vertical_spacing)
        elif align == 'right':
            ptext[line].shift(width/2-widths[line],-line*vertical_spacing)
        else:
            ptext[line].shift(-widths[line]/2,-line*vertical_spacing)
        ptext[line].shift(pos[0], pos[1])
        if rotate != 0.0: ptext[line].rotate(rotate)
        if line == 0:
            shape = ptext[0]
            upper_left = vis.vector(ptext[line].boundingBox()[0],ptext[line].boundingBox()[3],0)
            upper_right = vis.vector(ptext[line].boundingBox()[1],ptext[line].boundingBox()[3],0)
            lower_left = vis.vector(ptext[line].boundingBox()[0],ptext[line].boundingBox()[2],0)
            lower_right = vis.vector(ptext[line].boundingBox()[1],ptext[line].boundingBox()[2],0)
        else:
            shape += ptext[line]
            xleft = ptext[line].boundingBox()[0]
            xright = ptext[line].boundingBox()[1]
            y = ptext[line].boundingBox()[2]
            if xleft < upper_left.x:
                upper_left.x = xleft
            if xright > upper_right.x:
                upper_right.x = xright
            lower_left = vis.vector(upper_left.x,ptext[line].boundingBox()[2],0)
            lower_right = vis.vector(upper_right.x,ptext[line].boundingBox()[2],0)

    dy = vis.vector(0,(upper_left.y-lower_left.y)/2-height,0)
    shape.shift(0,dy.y)
    if not info: return shape

    info = text_info()
    info.Polygon = shape
    info.upper_left = upper_left+dy
    info.upper_right = upper_right+dy
    info.lower_left = lower_left+dy
    info.lower_right = lower_right+dy
    if align == 'left':
        x = 0
    elif align == 'right':
        x = -width
    elif align == 'center':
        x = -0.5*width
    info.start = vis.vector(x,0,0)+dy
    info.starts = []
    for line in range(len(lines)):
        if align == 'left':
            x = 0
        elif align == 'right':
            x = -widths[line]
        elif align == 'center':
            x = -0.5*widths[line]
        info.starts.append(vis.vector(x,line*vertical_spacing,0)+dy)
    
    info.width = width
    info.widths = widths
    info.descent = descent
    info.vertical_spacing = vertical_spacing
    info.align = align
    info.height = height
    
    return info