def compile(self, ttFont): if ttFont.recalcBBoxes: # For TT-flavored fonts, xMin, yMin, xMax and yMax are set in table__m_a_x_p.recalc(). if 'CFF ' in ttFont: topDict = ttFont['CFF '].cff.topDictIndex[0] self.xMin, self.yMin, self.xMax, self.yMax = intRect( topDict.FontBBox) elif 'CFF2' in ttFont: topDict = ttFont['CFF2'].cff.topDictIndex[0] charStrings = topDict.CharStrings fontBBox = None for charString in charStrings.values(): bounds = charString.calcBounds(charStrings) if bounds is not None: if fontBBox is not None: fontBBox = unionRect(fontBBox, bounds) else: fontBBox = bounds if fontBBox is not None: self.xMin, self.yMin, self.xMax, self.yMax = intRect( fontBBox) if ttFont.recalcTimestamp: self.modified = timestampNow() data = sstruct.pack(headFormat, self) return data
def compile(self, ttFont): if ttFont.recalcBBoxes: # For TT-flavored fonts, xMin, yMin, xMax and yMax are set in table__m_a_x_p.recalc(). if 'CFF ' in ttFont: topDict = ttFont['CFF '].cff.topDictIndex[0] self.xMin, self.yMin, self.xMax, self.yMax = intRect( topDict.FontBBox) if ttFont.recalcTimestamp: self.modified = timestampNow() data = sstruct.pack(headFormat, self) return data
def buildClipBox(clipBox: _ClipBoxInput) -> ot.ClipBox: if isinstance(clipBox, ot.ClipBox): return clipBox n = len(clipBox) clip = ot.ClipBox() if n not in (4, 5): raise ValueError(f"Invalid ClipBox: expected 4 or 5 values, found {n}") clip.xMin, clip.yMin, clip.xMax, clip.yMax = intRect(clipBox[:4]) clip.Format = int(n == 5) + 1 if n == 5: clip.VarIndexBase = int(clipBox[4]) return clip
def estimateCOLRv1BoundingBoxes(vcFont, ttFont, neutralOnly): from fontTools.pens.ttGlyphPen import TTGlyphPointPen from fontTools.pens.boundsPen import ControlBoundsPen locations = [{}] if not neutralOnly: for axis in ttFont["fvar"].axes: if axis.flags & 0x0001: # hidden axis continue values = {0} if axis.minValue < axis.defaultValue: values.add(-1) if axis.defaultValue < axis.maxValue: values.add(1) locations = [ dictUpdate(loc, axis.axisTag, v) for loc in locations for v in sorted(values) ] glyfTable = ttFont["glyf"] gvarTable = ttFont["gvar"] hmtxTable = ttFont["hmtx"] # TODO: fix tsb if we have "vmtx" for glyphName in sorted(vcFont.keys()): glyph = vcFont[glyphName] if not glyph.components or not glyph.outline.isEmpty(): continue # calculate the bounding box that would fit on all locations bpen = ControlBoundsPen(None) for loc in locations: vcFont.drawGlyph(bpen, glyphName, loc) gvarTable.variations.pop(glyphName, None) pen = TTGlyphPointPen(None) if bpen.bounds is not None: bounds = intRect(bpen.bounds) for pt in [bounds[:2], bounds[2:]]: pen.beginPath() pen.addPoint(pt, segmentType="line") pen.endPath() glyfTable[glyphName] = pen.glyph() adv, lsb = hmtxTable.metrics[glyphName] hmtxTable.metrics[glyphName] = adv, bounds[0]
def test_intRect(): assert intRect((0.9, 2.9, 3.1, 4.1)) == (0, 2, 4, 5)