def test_even_odd_fill(self):
     pen = FreeTypePen(None)
     star(pen)
     t = Scale(0.05, 0.05)
     width, height = t.transformPoint((1000, 1000))
     t = t.translate(0, 200)
     buf1, size1 = pen.buffer(width=width,
                              height=height,
                              transform=t,
                              evenOdd=True)
     buf2, size2 = load_pgm(os.path.join(DATA_DIR,
                                         "test_even_odd_fill.pgm"))
     self.assertEqual(len(buf1), len(buf2))
     self.assertEqual(size1, size2)
     self.assertGreater(psnr(buf1, buf2), PSNR_THRESHOLD)
Example #2
0
def main(argv):
    if len(argv) != 2:
        sys.stderr.write(
            "Please enter paths to two font files for center of mass comparisons"
            + os.linesep)
        sys.exit(1)

    test_glyphs = ('uni002B', 'uni002E')

    font1 = TTFont(argv[0])
    font2 = TTFont(argv[1])

    test_fonts = (font1, font2)

    for glyph_name in test_glyphs:
        print("\nGLYPH: " + glyph_name)
        x = 0
        for font in test_fonts:
            x += 1
            print("Font " + str(x))
            this_glyphset = font.getGlyphSet()
            glyph_obj = this_glyphset[glyph_name]
            stats_pen = StatisticsPen(glyphset=this_glyphset)
            upem = font['head'].unitsPerEm
            transformer = TransformPen(stats_pen, Scale(1. / upem))
            glyph_obj.draw(transformer)

            for item in ['area', 'meanX', 'meanY']:
                print("%s: %g" % (item, getattr(stats_pen, item)))

            print(" ")

        print(" ")
 def test_skew(self):
     pen = FreeTypePen(None)
     box(pen)
     t = Scale(0.05, 0.05).skew(math.pi / 4.0).translate(1234, 5678)
     width, height = None, None
     buf1, size1 = pen.buffer(width=width, height=height, transform=t)
     buf2, size2 = load_pgm(os.path.join(DATA_DIR, "test_skew.pgm"))
     self.assertEqual(len(buf1), len(buf2))
     self.assertEqual(size1, size2)
     self.assertGreater(psnr(buf1, buf2), PSNR_THRESHOLD)
Example #4
0
def test(glyphset, upem, glyphs):
    print('upem', upem)

    for glyph_name in glyphs:
        print()
        print("glyph:", glyph_name)
        glyph = glyphset[glyph_name]
        stats = GlyphStatistics(glyph,
                                transform=Scale(1. / upem),
                                glyphset=glyphset)
        for item in dir(stats):
            if item[0] == '_': continue
            print("%s: %g" % (item, getattr(stats, item)))
 def test_contain(self):
     pen = FreeTypePen(None)
     star(pen)
     t = Scale(0.05, 0.05)
     width, height = 0, 0
     buf1, size1 = pen.buffer(width=width,
                              height=height,
                              transform=t,
                              contain=True)
     buf2, size2 = load_pgm(os.path.join(DATA_DIR,
                                         "test_non_zero_fill.pgm"))
     self.assertEqual(len(buf1), len(buf2))
     self.assertEqual(size1, size2)
     self.assertGreater(psnr(buf1, buf2), PSNR_THRESHOLD)
Example #6
0
def _test(glyphset, upem, glyphs):
    from fontTools.pens.transformPen import TransformPen
    from fontTools.misc.transform import Scale

    print('upem', upem)

    for glyph_name in glyphs:
        print()
        print("glyph:", glyph_name)
        glyph = glyphset[glyph_name]
        pen = StatisticsPen(glyphset=glyphset)
        transformer = TransformPen(pen, Scale(1. / upem))
        glyph.draw(transformer)
        for item in [
                'area', 'momentX', 'momentY', 'momentXX', 'momentYY',
                'momentXY', 'meanX', 'meanY', 'varianceX', 'varianceY',
                'stddevX', 'stddevY', 'covariance', 'correlation', 'slant'
        ]:
            print("%s: %g" % (item, getattr(pen, item)))
Example #7
0
    def changeUPM(self, targetUPM):
        # Calculate scaling factor between old and new UPM
        upmOld = self.font["head"].unitsPerEm
        upmNew = int(targetUPM)
        isCubic = self.font.has_key("CFF ")
        if upmOld == upmNew:
            return
        elif upmNew < 16 or upmNew > 16384:
            print("WARNING: Invalid UPM value. --UPM is now ignored.",
                  file=sys.stderr)
            return
        elif isCubic:
            print(
                "WARNING: CFF-based font detected. Unfortunately it is currently not supported.",
                file=sys.stderr)
            return
        elif upmNew > 5000:
            print(
                "WARNING: UPM > 5000 will cause problems in Adobe InDesign and Illustrator.",
                file=sys.stderr)
        else:
            pass
        scaleFactor = upmNew / upmOld  # Get float because __future__.division has been imported

        # Conversion: re-scale all glyphs
        scaledGlyphs = {}
        glyphOrder = self.font.getGlyphOrder()
        glyphSet = self.font.getGlyphSet()
        for glyphName in glyphSet.keys():
            glyph = glyphSet[glyphName]
            if isCubic:  # TODO: `CFF `
                # basePen = OTGlyphPen(glyphSet)
                pass
            else:  # `glyf`
                basePen = TTGlyphPen(glyphSet)
            scalePen = TransformPen(basePen, Scale(scaleFactor, scaleFactor))
            # Deal with quad composites (all cubics are not affected)
            if not isCubic and glyph._glyph.isComposite(
            ):  # Scale each component's xy offset
                glyph.draw(basePen)
                for i in range(len(basePen.components)):
                    componentName, oldTrans = basePen.components[i]
                    newTrans = (oldTrans[0], oldTrans[1], oldTrans[2],
                                oldTrans[3], oldTrans[4] * scaleFactor,
                                oldTrans[5] * scaleFactor)
                    basePen.components[i] = (componentName, newTrans)
            else:  # Scale all cubics or base quads so that their composites will not be scaled multiple times
                glyph.draw(scalePen)
            # Glyph-specific hinting will be removed upon TTGlyphPen.glyph() call.
            scaledGlyphs[glyphName] = basePen.glyph()

        # Apply `glyf` table with scaled glyphs
        glyf = newTable("glyf")
        glyf.glyphOrder = glyphOrder
        glyf.glyphs = scaledGlyphs
        self.font["glyf"] = glyf

        # Update tables to apply the new UPM
        self.__applyNewUPM(upmOld, upmNew)

        # Recalculate `head`, `glyf`, `maxp` upon compile
        self.font.recalcBBoxes = True
        return
Example #8
0
 def test_Scale(self):
     assert Scale(1) == Transform(1, 0, 0, 1, 0, 0)
     assert Scale(2) == Transform(2, 0, 0, 2, 0, 0)
     assert Scale(1, 2) == Transform(1, 0, 0, 2, 0, 0)
Example #9
0
    def _parametrize(self):
        # convert from endopoint to center parametrization:
        # https://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter

        # If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a
        # "lineto") joining the endpoints.
        # http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters
        rx = fabs(self.rx)
        ry = fabs(self.ry)
        if not (rx and ry):
            return False

        # If the current point and target point for the arc are identical, it should
        # be treated as a zero length path. This ensures continuity in animations.
        if self.target_point == self.current_point:
            return False

        mid_point_distance = (self.current_point - self.target_point) * 0.5

        point_transform = Identity.rotate(-self.angle)

        transformed_mid_point = _map_point(point_transform, mid_point_distance)
        square_rx = rx * rx
        square_ry = ry * ry
        square_x = transformed_mid_point.real * transformed_mid_point.real
        square_y = transformed_mid_point.imag * transformed_mid_point.imag

        # Check if the radii are big enough to draw the arc, scale radii if not.
        # http://www.w3.org/TR/SVG/implnote.html#ArcCorrectionOutOfRangeRadii
        radii_scale = square_x / square_rx + square_y / square_ry
        if radii_scale > 1:
            rx *= sqrt(radii_scale)
            ry *= sqrt(radii_scale)
            self.rx, self.ry = rx, ry

        point_transform = Scale(1 / rx, 1 / ry).rotate(-self.angle)

        point1 = _map_point(point_transform, self.current_point)
        point2 = _map_point(point_transform, self.target_point)
        delta = point2 - point1

        d = delta.real * delta.real + delta.imag * delta.imag
        scale_factor_squared = max(1 / d - 0.25, 0.0)

        scale_factor = sqrt(scale_factor_squared)
        if self.sweep == self.large:
            scale_factor = -scale_factor

        delta *= scale_factor
        center_point = (point1 + point2) * 0.5
        center_point += complex(-delta.imag, delta.real)
        point1 -= center_point
        point2 -= center_point

        theta1 = atan2(point1.imag, point1.real)
        theta2 = atan2(point2.imag, point2.real)

        theta_arc = theta2 - theta1
        if theta_arc < 0 and self.sweep:
            theta_arc += TWO_PI
        elif theta_arc > 0 and not self.sweep:
            theta_arc -= TWO_PI

        self.theta1 = theta1
        self.theta2 = theta1 + theta_arc
        self.theta_arc = theta_arc
        self.center_point = center_point

        return True