コード例 #1
0
    def buildPaintRadialGradient(
        self,
        colorLine: _ColorLineInput,
        c0: _PointTuple,
        c1: _PointTuple,
        r0: _ScalarInput,
        r1: _ScalarInput,
    ) -> ot.Paint:

        ot_paint = ot.Paint()
        ot_paint.Format = int(ot.Paint.Format.PaintRadialGradient)
        ot_paint.ColorLine = _to_color_line(colorLine)

        # normalize input types (which may or may not specify a varIdx)
        x0, y0 = _to_variable_value(c0[0]), _to_variable_value(c0[1])
        r0 = _to_variable_value(r0)
        x1, y1 = _to_variable_value(c1[0]), _to_variable_value(c1[1])
        r1 = _to_variable_value(r1)

        # avoid abrupt change after rounding when c0 is near c1's perimeter
        c = round_start_circle_stable_containment(
            (x0.value, y0.value), r0.value, (x1.value, y1.value), r1.value)
        x0, y0 = x0._replace(value=c.centre[0]), y0._replace(value=c.centre[1])
        r0 = r0._replace(value=c.radius)

        for i, (x, y, r) in enumerate(((x0, y0, r0), (x1, y1, r1))):
            # rounding happens here as floats are converted to integers
            setattr(ot_paint, f"x{i}", _to_variable_int16(x))
            setattr(ot_paint, f"y{i}", _to_variable_int16(y))
            setattr(ot_paint, f"r{i}", _to_variable_uint16(r))

        return ot_paint
コード例 #2
0
ファイル: builder.py プロジェクト: kpozin/fonttools
def buildSolidColorPaint(
        paletteIndex: int,
        transparency: _ScalarInput = _DEFAULT_TRANSPARENCY) -> ot.Paint:
    self = ot.Paint()
    self.Format = 1
    self.Color = buildColor(paletteIndex, transparency)
    return self
コード例 #3
0
ファイル: builder.py プロジェクト: verbosus/fonttools
 def buildPaintSolid(self,
                     paletteIndex: int,
                     alpha: _ScalarInput = _DEFAULT_ALPHA) -> ot.Paint:
     ot_paint = ot.Paint()
     ot_paint.Format = int(ot.Paint.Format.PaintSolid)
     ot_paint.Color = buildColorIndex(paletteIndex, alpha)
     return ot_paint
コード例 #4
0
ファイル: builder.py プロジェクト: kpozin/fonttools
def buildRadialGradientPaint(
    colorLine: _ColorLineInput,
    c0: _PointInput,
    c1: _PointInput,
    r0: _ScalarInput,
    r1: _ScalarInput,
    affine: Optional[_AffineInput] = None,
) -> ot.Paint:

    self = ot.Paint()
    self.Format = 3
    self.ColorLine = _to_color_line(colorLine)

    for i, pt in [(0, c0), (1, c1)]:
        setattr(self, f"c{i}", _to_variable_point(pt))

    for i, r in [(0, r0), (1, r1)]:
        # distances are encoded as UShort so we round to int
        setattr(self, f"r{i}", _to_variable_int(r))

    if affine is not None and not isinstance(affine, ot.Affine2x2):
        affine = buildAffine2x2(*affine)
    self.Affine = affine

    return self
コード例 #5
0
ファイル: builder.py プロジェクト: timgates42/fonttools
 def buildPaintTranslate(self, paint: _PaintInput, dx: _ScalarInput,
                         dy: _ScalarInput):
     ot_paint = ot.Paint()
     ot_paint.Format = int(ot.Paint.Format.PaintTranslate)
     ot_paint.Paint = self.buildPaint(paint)
     ot_paint.dx = _to_variable_f16dot16_float(dx)
     ot_paint.dy = _to_variable_f16dot16_float(dy)
     return ot_paint
コード例 #6
0
ファイル: builder.py プロジェクト: verbosus/fonttools
 def buildPaintTransform(self, transform: _AffineInput,
                         paint: _PaintInput) -> ot.Paint:
     ot_paint = ot.Paint()
     ot_paint.Format = int(ot.Paint.Format.PaintTransform)
     if not isinstance(transform, ot.Affine2x3):
         transform = buildAffine2x3(transform)
     ot_paint.Transform = transform
     ot_paint.Paint = self.buildPaint(paint)
     return ot_paint
コード例 #7
0
    def buildColrLayers(self, paints: List[_PaintInput]) -> ot.Paint:
        ot_paint = ot.Paint()
        ot_paint.Format = int(ot.Paint.Format.PaintColrLayers)
        self.slices.append(ot_paint)

        paints = [
            self.buildPaint(p)
            for p in _build_n_ary_tree(paints, n=MAX_PAINT_COLR_LAYER_COUNT)
        ]

        # Look for reuse, with preference to longer sequences
        found_reuse = True
        while found_reuse:
            found_reuse = False

            ranges = sorted(
                _reuse_ranges(len(paints)),
                key=lambda t: (t[1] - t[0], t[1], t[0]),
                reverse=True,
            )
            for lbound, ubound in ranges:
                reuse_lbound = self.reusePool.get(
                    self._as_tuple(paints[lbound:ubound]), -1)
                if reuse_lbound == -1:
                    continue
                new_slice = ot.Paint()
                new_slice.Format = int(ot.Paint.Format.PaintColrLayers)
                new_slice.NumLayers = ubound - lbound
                new_slice.FirstLayerIndex = reuse_lbound
                paints = paints[:lbound] + [new_slice] + paints[ubound:]
                found_reuse = True
                break

        ot_paint.NumLayers = len(paints)
        ot_paint.FirstLayerIndex = len(self.layers)
        self.layers.extend(paints)

        # Register our parts for reuse
        for lbound, ubound in _reuse_ranges(len(paints)):
            self.reusePool[self._as_tuple(
                paints[lbound:ubound])] = (lbound + ot_paint.FirstLayerIndex)

        return ot_paint
コード例 #8
0
ファイル: builder.py プロジェクト: googlefonts/fonttools
    def _beforeBuildPaintColrLayers(self, dest, source):
        # Sketchy gymnastics: a sequence input will have dropped it's layers
        # into NumLayers; get it back
        if isinstance(source.get("NumLayers", None), collections.abc.Sequence):
            layers = source["NumLayers"]
        else:
            layers = source["Layers"]

        # Convert maps seqs or whatever into typed objects
        layers = [self.buildPaint(l) for l in layers]

        # No reason to have a colr layers with just one entry
        if len(layers) == 1:
            return layers[0], {}

        if self.cache is not None:
            # Look for reuse, with preference to longer sequences
            # This may make the layer list smaller
            layers = self.cache.try_reuse(layers)

        # The layer list is now final; if it's too big we need to tree it
        is_tree = len(layers) > MAX_PAINT_COLR_LAYER_COUNT
        layers = build_n_ary_tree(layers, n=MAX_PAINT_COLR_LAYER_COUNT)

        # We now have a tree of sequences with Paint leaves.
        # Convert the sequences into PaintColrLayers.
        def listToColrLayers(layer):
            if isinstance(layer, collections.abc.Sequence):
                return self.buildPaint(
                    {
                        "Format": ot.PaintFormat.PaintColrLayers,
                        "Layers": [listToColrLayers(l) for l in layer],
                    }
                )
            return layer

        layers = [listToColrLayers(l) for l in layers]

        # No reason to have a colr layers with just one entry
        if len(layers) == 1:
            return layers[0], {}

        paint = ot.Paint()
        paint.Format = int(ot.PaintFormat.PaintColrLayers)
        paint.NumLayers = len(layers)
        paint.FirstLayerIndex = len(self.layers)
        self.layers.extend(layers)

        # Register our parts for reuse provided we aren't a tree
        # If we are a tree the leaves registered for reuse and that will suffice
        if self.cache is not None and not is_tree:
            self.cache.add(layers, paint.FirstLayerIndex)

        # we've fully built dest; empty source prevents generalized build from kicking in
        return paint, {}
コード例 #9
0
ファイル: merger.py プロジェクト: googlefonts/fonttools
	def listToColrLayers(paint):
		if isinstance(paint, list):
			layers = [listToColrLayers(l) for l in paint]
			paint = ot.Paint()
			paint.Format = int(ot.PaintFormat.PaintColrLayers)
			paint.NumLayers = len(layers)
			paint.FirstLayerIndex = len(self.layers)
			self.layers.extend(layers)
			if self.layerReuseCache is not None:
				self.layerReuseCache.add(layers, paint.FirstLayerIndex)
		return paint
コード例 #10
0
ファイル: builder.py プロジェクト: verbosus/fonttools
 def buildPaintComposite(
     self,
     mode: _CompositeInput,
     source: _PaintInput,
     backdrop: _PaintInput,
 ):
     ot_paint = ot.Paint()
     ot_paint.Format = int(ot.Paint.Format.PaintComposite)
     ot_paint.SourcePaint = self.buildPaint(source)
     ot_paint.CompositeMode = _to_composite_mode(mode)
     ot_paint.BackdropPaint = self.buildPaint(backdrop)
     return ot_paint
コード例 #11
0
ファイル: builder.py プロジェクト: verbosus/fonttools
 def buildPaintRotate(
     self,
     paint: _PaintInput,
     angle: _ScalarInput,
     centerX: _ScalarInput,
     centerY: _ScalarInput,
 ) -> ot.Paint:
     ot_paint = ot.Paint()
     ot_paint.Format = int(ot.Paint.Format.PaintRotate)
     ot_paint.Paint = self.buildPaint(paint)
     ot_paint.angle = _to_variable_f16dot16_float(angle)
     ot_paint.centerX = _to_variable_f16dot16_float(centerX)
     ot_paint.centerY = _to_variable_f16dot16_float(centerY)
     return ot_paint
コード例 #12
0
ファイル: builder.py プロジェクト: kpozin/fonttools
def buildLinearGradientPaint(
    colorLine: _ColorLineInput,
    p0: _PointInput,
    p1: _PointInput,
    p2: Optional[_PointInput] = None,
) -> ot.Paint:
    self = ot.Paint()
    self.Format = 2
    self.ColorLine = _to_color_line(colorLine)

    if p2 is None:
        p2 = copy.copy(p1)
    for i, pt in enumerate((p0, p1, p2)):
        setattr(self, f"p{i}", _to_variable_point(pt))

    return self
コード例 #13
0
 def buildPaintSweepGradient(
     self,
     colorLine: _ColorLineInput,
     centerX: _ScalarInput,
     centerY: _ScalarInput,
     startAngle: _ScalarInput,
     endAngle: _ScalarInput,
 ) -> ot.Paint:
     ot_paint = ot.Paint()
     ot_paint.Format = int(ot.PaintFormat.PaintSweepGradient)
     ot_paint.ColorLine = _to_color_line(colorLine)
     ot_paint.centerX = _to_variable_int16(centerX)
     ot_paint.centerY = _to_variable_int16(centerY)
     ot_paint.startAngle = _to_variable_f16dot16_float(startAngle)
     ot_paint.endAngle = _to_variable_f16dot16_float(endAngle)
     return ot_paint
コード例 #14
0
ファイル: builder.py プロジェクト: verbosus/fonttools
 def buildPaintSkew(
     self,
     paint: _PaintInput,
     xSkewAngle: _ScalarInput,
     ySkewAngle: _ScalarInput,
     centerX: _ScalarInput,
     centerY: _ScalarInput,
 ) -> ot.Paint:
     ot_paint = ot.Paint()
     ot_paint.Format = int(ot.Paint.Format.PaintSkew)
     ot_paint.Paint = self.buildPaint(paint)
     ot_paint.xSkewAngle = _to_variable_f16dot16_float(xSkewAngle)
     ot_paint.ySkewAngle = _to_variable_f16dot16_float(ySkewAngle)
     ot_paint.centerX = _to_variable_f16dot16_float(centerX)
     ot_paint.centerY = _to_variable_f16dot16_float(centerY)
     return ot_paint
コード例 #15
0
ファイル: builder.py プロジェクト: verbosus/fonttools
    def buildPaintLinearGradient(
        self,
        colorLine: _ColorLineInput,
        p0: _PointTuple,
        p1: _PointTuple,
        p2: Optional[_PointTuple] = None,
    ) -> ot.Paint:
        ot_paint = ot.Paint()
        ot_paint.Format = int(ot.Paint.Format.PaintLinearGradient)
        ot_paint.ColorLine = _to_color_line(colorLine)

        if p2 is None:
            p2 = copy.copy(p1)
        for i, (x, y) in enumerate((p0, p1, p2)):
            setattr(ot_paint, f"x{i}", _to_variable_int16(x))
            setattr(ot_paint, f"y{i}", _to_variable_int16(y))

        return ot_paint
コード例 #16
0
ファイル: builder.py プロジェクト: verbosus/fonttools
    def buildPaintRadialGradient(
        self,
        colorLine: _ColorLineInput,
        c0: _PointTuple,
        c1: _PointTuple,
        r0: _ScalarInput,
        r1: _ScalarInput,
    ) -> ot.Paint:

        ot_paint = ot.Paint()
        ot_paint.Format = int(ot.Paint.Format.PaintRadialGradient)
        ot_paint.ColorLine = _to_color_line(colorLine)

        for i, (x, y), r in [(0, c0, r0), (1, c1, r1)]:
            setattr(ot_paint, f"x{i}", _to_variable_int16(x))
            setattr(ot_paint, f"y{i}", _to_variable_int16(y))
            setattr(ot_paint, f"r{i}", _to_variable_uint16(r))

        return ot_paint
コード例 #17
0
ファイル: builder.py プロジェクト: ollawone/stdm
def buildRadialGradientPaint(
    colorLine: _ColorLineInput,
    c0: _PointTuple,
    c1: _PointTuple,
    r0: _ScalarInput,
    r1: _ScalarInput,
    transform: Optional[_AffineInput] = None,
) -> ot.Paint:

    self = ot.Paint()
    self.Format = 3
    self.ColorLine = _to_color_line(colorLine)

    for i, (x, y), r in [(0, c0, r0), (1, c1, r1)]:
        setattr(self, f"x{i}", _to_variable_int(x))
        setattr(self, f"y{i}", _to_variable_int(y))
        setattr(self, f"r{i}", _to_variable_int(r))

    if transform is not None and not isinstance(transform, ot.Affine2x2):
        transform = buildAffine2x2(*transform)
    self.Transform = transform

    return self
コード例 #18
0
ファイル: builder.py プロジェクト: googlefonts/fonttools
    def try_reuse(self, layers: List[ot.Paint]) -> List[ot.Paint]:
        found_reuse = True
        while found_reuse:
            found_reuse = False

            ranges = sorted(
                _reuse_ranges(len(layers)),
                key=lambda t: (t[1] - t[0], t[1], t[0]),
                reverse=True,
            )
            for lbound, ubound in ranges:
                reuse_lbound = self.reusePool.get(
                    self._as_tuple(layers[lbound:ubound]), -1
                )
                if reuse_lbound == -1:
                    continue
                new_slice = ot.Paint()
                new_slice.Format = int(ot.PaintFormat.PaintColrLayers)
                new_slice.NumLayers = ubound - lbound
                new_slice.FirstLayerIndex = reuse_lbound
                layers = layers[:lbound] + [new_slice] + layers[ubound:]
                found_reuse = True
                break
        return layers
コード例 #19
0
ファイル: builder.py プロジェクト: ollawone/stdm
def buildSolidColorPaint(paletteIndex: int,
                         alpha: _ScalarInput = _DEFAULT_ALPHA) -> ot.Paint:
    self = ot.Paint()
    self.Format = 1
    self.Color = buildColorIndex(paletteIndex, alpha)
    return self
コード例 #20
0
ファイル: builder.py プロジェクト: MarceloDL-A/metodos_python
def _defaultPaintSolid():
    paint = ot.Paint()
    paint.Alpha = _DEFAULT_ALPHA
    return paint
コード例 #21
0
ファイル: builder.py プロジェクト: verbosus/fonttools
 def buildPaintColrGlyph(self, glyph: str) -> ot.Paint:
     ot_paint = ot.Paint()
     ot_paint.Format = int(ot.Paint.Format.PaintColrGlyph)
     ot_paint.Glyph = glyph
     return ot_paint
コード例 #22
0
ファイル: builder.py プロジェクト: verbosus/fonttools
 def buildPaintGlyph(self, glyph: str, paint: _PaintInput) -> ot.Paint:
     ot_paint = ot.Paint()
     ot_paint.Format = int(ot.Paint.Format.PaintGlyph)
     ot_paint.Glyph = glyph
     ot_paint.Paint = self.buildPaint(paint)
     return ot_paint
コード例 #23
0
ファイル: builder.py プロジェクト: MarceloDL-A/metodos_python
    def _beforeBuildPaintColrLayers(self, dest, source):
        # Sketchy gymnastics: a sequence input will have dropped it's layers
        # into NumLayers; get it back
        if isinstance(source.get("NumLayers", None), collections.abc.Sequence):
            layers = source["NumLayers"]
        else:
            layers = source["Layers"]

        # Convert maps seqs or whatever into typed objects
        layers = [self.buildPaint(l) for l in layers]

        # No reason to have a colr layers with just one entry
        if len(layers) == 1:
            return layers[0], {}

        # Look for reuse, with preference to longer sequences
        # This may make the layer list smaller
        found_reuse = True
        while found_reuse:
            found_reuse = False

            ranges = sorted(
                _reuse_ranges(len(layers)),
                key=lambda t: (t[1] - t[0], t[1], t[0]),
                reverse=True,
            )
            for lbound, ubound in ranges:
                reuse_lbound = self.reusePool.get(
                    self._as_tuple(layers[lbound:ubound]), -1)
                if reuse_lbound == -1:
                    continue
                new_slice = ot.Paint()
                new_slice.Format = int(ot.PaintFormat.PaintColrLayers)
                new_slice.NumLayers = ubound - lbound
                new_slice.FirstLayerIndex = reuse_lbound
                layers = layers[:lbound] + [new_slice] + layers[ubound:]
                found_reuse = True
                break

        # The layer list is now final; if it's too big we need to tree it
        is_tree = len(layers) > MAX_PAINT_COLR_LAYER_COUNT
        layers = _build_n_ary_tree(layers, n=MAX_PAINT_COLR_LAYER_COUNT)

        # We now have a tree of sequences with Paint leaves.
        # Convert the sequences into PaintColrLayers.
        def listToColrLayers(layer):
            if isinstance(layer, collections.abc.Sequence):
                return self.buildPaint({
                    "Format":
                    ot.PaintFormat.PaintColrLayers,
                    "Layers": [listToColrLayers(l) for l in layer],
                })
            return layer

        layers = [listToColrLayers(l) for l in layers]

        # No reason to have a colr layers with just one entry
        if len(layers) == 1:
            return layers[0], {}

        paint = ot.Paint()
        paint.Format = int(ot.PaintFormat.PaintColrLayers)
        paint.NumLayers = len(layers)
        paint.FirstLayerIndex = len(self.layers)
        self.layers.extend(layers)

        # Register our parts for reuse provided we aren't a tree
        # If we are a tree the leaves registered for reuse and that will suffice
        if not is_tree:
            for lbound, ubound in _reuse_ranges(len(layers)):
                self.reusePool[self._as_tuple(
                    layers[lbound:ubound])] = (lbound + paint.FirstLayerIndex)

        # we've fully built dest; empty source prevents generalized build from kicking in
        return paint, {}