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
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
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
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
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
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
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)]
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)
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
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)]