Esempio n. 1
0
 def _get_controlPointBounds(self):
     from fontTools.misc.transform import Transform
     # storage
     glyphRects = {}
     componentReferences = {}
     # scan loaded glyphs
     for glyphName, glyph in self._glyphs.items():
         if glyphName in self._scheduledForDeletion:
             continue
         glyphRect = glyph.controlPointBounds
         if glyphRect:
             glyphRects[glyphName] = glyphRect
     # scan glyphs that have not been loaded
     if self._glyphSet is not None:
         for glyphName, fileName in self._glyphSet.contents.items():
             if glyphName in self._glyphs or glyphName in self._scheduledForDeletion:
                 continue
             glif = self._glyphSet.getGLIF(glyphName)
             points, components = _fetchControlPointBoundsData(glif)
             if points:
                 glyphRects[glyphName] = calcBounds(points)
             for base, transformation in components:
                 xScale, xyScale, yxScale, yScale, xOffset, yOffset = transformation
                 if glyphName not in componentReferences:
                     componentReferences[glyphName] = []
                 componentReferences[glyphName].append((base, xScale, xyScale, yxScale, yScale, xOffset, yOffset))
     # get the transformed component bounding boxes and update the glyphs
     for glyphName, components in componentReferences.items():
         glyphRect = glyphRects.get(glyphName, (None, None, None, None))
         # XXX this doesn't handle nested components
         for base, xScale, xyScale, yxScale, yScale, xOffset, yOffset in components:
             # base glyph doesn't exist
             if base not in glyphRects:
                 continue
             baseRect = glyphRects[base]
             # base glyph has no points
             if None in baseRect:
                 continue
             # transform the base rect
             transform = Transform(xx=xScale, xy=xyScale, yx=yxScale, yy=yScale, dx=xOffset, dy=yOffset)
             xMin, yMin, xMax, yMax = baseRect
             (xMin, yMin), (xMax, yMax) = transform.transformPoints([(xMin, yMin), (xMax, yMax)])
             componentRect = (xMin, yMin, xMax, yMax)
             # update the glyph rect
             if None in glyphRect:
                 glyphRect = componentRect
             else:
                 glyphRect = unionRect(glyphRect, componentRect)
         # store the updated rect
         glyphRects[glyphName] = glyphRect
     # work out the unified rect
     fontRect = None
     for glyphRect in glyphRects.values():
         if fontRect is None:
             fontRect = glyphRect
         elif glyphRect is not None:
             fontRect = unionRect(fontRect, glyphRect)
     # done
     return fontRect
Esempio n. 2
0
 def _getBounds(self, boundsAttr):
     layer = self.layer
     if layer is None:
         return None
     if self.baseGlyph not in layer:
         return None
     glyph = layer[self.baseGlyph]
     bounds = getattr(glyph, boundsAttr)
     if bounds is None:
         return None
     if self.transformation == _defaultTransformation:
         return bounds
     xMin, yMin, xMax, yMax = bounds
     t = Transform(*self.transformation)
     points = [(xMin, yMin), (xMax, yMax)]
     (xMin, yMin), (xMax, yMax) = t.transformPoints(points)
     return xMin, yMin, xMax, yMax
Esempio n. 3
0
 def _getBounds(self, boundsAttr):
     layer = self.layer
     if layer is None:
         return None
     if self.baseGlyph not in layer:
         return None
     glyph = layer[self.baseGlyph]
     bounds = getattr(glyph, boundsAttr)
     if bounds is None:
         return None
     if self.transformation == _defaultTransformation:
         return bounds
     xMin, yMin, xMax, yMax = bounds
     t = Transform(*self.transformation)
     points = [(xMin, yMin), (xMax, yMax)]
     (xMin, yMin), (xMax, yMax) = t.transformPoints(points)
     return xMin, yMin, xMax, yMax
Esempio n. 4
0
 def _getBounds(self, boundsAttr):
     glyph = self.getParent()
     if glyph is None:
         return None
     font = glyph.getParent()
     if font is None:
         return None
     if self.baseGlyph not in font:
         return None
     glyph = font[self.baseGlyph]
     bounds = getattr(glyph, boundsAttr)
     if bounds is None:
         return None
     if self.transformation == _defaultTransformation:
         return bounds
     xMin, yMin, xMax, yMax = bounds
     t = Transform(*self.transformation)
     points = [(xMin, yMin), (xMax, yMax)]
     (xMin, yMin), (xMax, yMax) = t.transformPoints(points)
     return xMin, yMin, xMax, yMax
Esempio n. 5
0
 def _getBounds(self, boundsAttr):
     glyph = self.getParent()
     if glyph is None:
         return None
     font = glyph.getParent()
     if font is None:
         return None
     if self.baseGlyph not in font:
         return None
     glyph = font[self.baseGlyph]
     bounds = getattr(glyph, boundsAttr)
     if bounds is None:
         return None
     if self.transformation == _defaultTransformation:
         return bounds
     xMin, yMin, xMax, yMax = bounds
     t = Transform(*self.transformation)
     points = [(xMin, yMin), (xMax, yMax)]
     (xMin, yMin), (xMax, yMax) = t.transformPoints(points)
     return xMin, yMin, xMax, yMax
Esempio n. 6
0
 def transform_nib_path(self, alpha):
     t = Transform().rotate(-alpha)
     self.nib_face_path_transformed = t.transformPoints(self.nib_face_path)
     self.cache_angle = alpha
Esempio n. 7
0
 def test_transformPoints(self):
     t = Transform(2, 0, 0, 3, 0, 0)
     assert t.transformPoints([(0, 0), (0, 100), (100, 100),
                               (100, 0)]) == [(0, 0), (0, 300), (200, 300),
                                              (200, 0)]
Esempio n. 8
0
    def buffer(self,
               width=None,
               height=None,
               transform=None,
               contain=False,
               evenOdd=False):
        """Renders the current contours within a bitmap buffer.

        Args:
            width: Image width of the bitmap in pixels. If omitted, it
                automatically fits to the bounding box of the contours.
            height: Image height of the bitmap in pixels. If omitted, it
                automatically fits to the bounding box of the contours.
            transform: A optional 6-tuple containing an affine transformation,
                or a ``Transform`` object from the ``fontTools.misc.transform``
                module. The bitmap size is not affected by this matrix.
            contain: If ``True``, the image size will be automatically expanded
                so that it fits to the bounding box of the paths. Useful for
                rendering glyphs with negative sidebearings without clipping.
            evenOdd: Pass ``True`` for even-odd fill instead of non-zero.

        Returns:
            A tuple of ``(buffer, size)``, where ``buffer`` is a ``bytes``
            object of the resulted bitmap and ``size`` is a 2-tuple of its
            dimension.

        :Example:
            .. code-block::
                
                >> pen = FreeTypePen(None)
                >> glyph.draw(pen)
                >> buf, size = pen.buffer(width=500, height=1000)
                >> type(buf), len(buf), size
                (<class 'bytes'>, 500000, (500, 1000))
        
        """
        transform = transform or Transform()
        if not hasattr(transform, 'transformPoint'):
            transform = Transform(*transform)
        contain_x, contain_y = contain or width is None, contain or height is None
        width, height = width or 0, height or 0
        if contain_x or contain_y:
            bbox = self.bbox
            bbox = transform.transformPoints((bbox[0:2], bbox[2:4]))
            bbox = (*bbox[0], *bbox[1])
            bbox_size = bbox[2] - bbox[0], bbox[3] - bbox[1]
            dx, dy = transform.dx, transform.dy
            if contain_x:
                dx = min(-dx, bbox[0]) * -1.0
                width = max(width, bbox_size[0])
            if contain_y:
                dy = min(-dy, bbox[1]) * -1.0
                height = max(height, bbox_size[1])
            transform = Transform(*transform[:4], dx, dy)
        width, height = math.ceil(width), math.ceil(height)
        buf = ctypes.create_string_buffer(width * height)
        bitmap = FT_Bitmap(
            (ctypes.c_int)(height), (ctypes.c_int)(width),
            (ctypes.c_int)(width), (ctypes.POINTER(ctypes.c_ubyte))(buf),
            (ctypes.c_short)(256), (ctypes.c_ubyte)(FT_PIXEL_MODE_GRAY),
            (ctypes.c_char)(0), (ctypes.c_void_p)(None))
        outline = self.outline(transform=transform, evenOdd=evenOdd)
        err = FT_Outline_Get_Bitmap(freetype.get_handle(),
                                    ctypes.byref(outline),
                                    ctypes.byref(bitmap))
        if err != 0:
            raise FT_Exception(err)
        return buf.raw, (width, height)
Esempio n. 9
0
 def _get_controlPointBounds(self):
     from fontTools.misc.transform import Transform
     # storage
     glyphRects = {}
     componentReferences = {}
     # scan loaded glyphs
     for glyphName, glyph in self._glyphs.items():
         if glyphName in self._scheduledForDeletion:
             continue
         glyphRect = glyph.controlPointBounds
         if glyphRect:
             glyphRects[glyphName] = glyphRect
     # scan glyphs that have not been loaded
     if self._glyphSet is not None:
         for glyphName, fileName in self._glyphSet.contents.items():
             if glyphName in self._glyphs or glyphName in self._scheduledForDeletion:
                 continue
             glif = self._glyphSet.getGLIF(glyphName)
             points, components = _fetchControlPointBoundsData(glif)
             if points:
                 glyphRects[glyphName] = calcBounds(points)
             for base, transformation in components:
                 xScale, xyScale, yxScale, yScale, xOffset, yOffset = transformation
                 if glyphName not in componentReferences:
                     componentReferences[glyphName] = []
                 componentReferences[glyphName].append(
                     (base, xScale, xyScale, yxScale, yScale, xOffset,
                      yOffset))
     # get the transformed component bounding boxes and update the glyphs
     for glyphName, components in componentReferences.items():
         glyphRect = glyphRects.get(glyphName, (None, None, None, None))
         # XXX this doesn't handle nested components
         for base, xScale, xyScale, yxScale, yScale, xOffset, yOffset in components:
             # base glyph doesn't exist
             if base not in glyphRects:
                 continue
             baseRect = glyphRects[base]
             # base glyph has no points
             if None in baseRect:
                 continue
             # transform the base rect
             transform = Transform(xx=xScale,
                                   xy=xyScale,
                                   yx=yxScale,
                                   yy=yScale,
                                   dx=xOffset,
                                   dy=yOffset)
             xMin, yMin, xMax, yMax = baseRect
             (xMin, yMin), (xMax, yMax) = transform.transformPoints([
                 (xMin, yMin), (xMax, yMax)
             ])
             componentRect = (xMin, yMin, xMax, yMax)
             # update the glyph rect
             if None in glyphRect:
                 glyphRect = componentRect
             else:
                 glyphRect = unionRect(glyphRect, componentRect)
         # store the updated rect
         glyphRects[glyphName] = glyphRect
     # work out the unified rect
     fontRect = None
     for glyphRect in glyphRects.values():
         if fontRect is None:
             fontRect = glyphRect
         elif glyphRect is not None:
             fontRect = unionRect(fontRect, glyphRect)
     # done
     return fontRect
Esempio n. 10
0
 def test_transformPoints(self):
     t = Transform(2, 0, 0, 3, 0, 0)
     assert t.transformPoints(
         [(0, 0), (0, 100), (100, 100), (100, 0)]
     ) == [(0, 0), (0, 300), (200, 300), (200, 0)]