1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# OT-SVG example with Skia
#
# Copyright 2023 Hin-Tak Leung
# Distributed under the terms of the new BSD license.
# This is an older example which works on skia m87 with known limitations.
# See "ot-svg-example-skia.py" for a full example which requires m117.
# Limitation:
# Skia-python bundles with Skia m87 (at time of writing this).
#
# Skia m88 is first version where SkSVG* is considered no longer experimental.
#
# Skia m103 is the first Skia build which contains 9cbadcd9280dc139af2f4d41d25a6c9a750e0302.
# That introduces "SkSVGDOM::renderNode()" among other stuff,
# necessary for rendering "some" OT-SVG fonts. Guess what, that commit
# is titled "Add optional OT-SVG support to FreeType"!
#
# So the example below only works correctly for "some" glyphs in
# "some other" OT-SVG fonts, and also with very limited functionality
# beyond what is used below.
#
# The missing functionality (and support for beyond Skia m103) is filed
# as skia-python issue #192.
from freetype import *
import skia
if __name__ == '__main__':
import sys
execname = sys.argv[0]
if len(sys.argv) < 2:
print("Example usage: %s TrajanColor-Concept.otf" % execname)
exit(1)
face = Face(sys.argv[1])
face.set_char_size( 160*64 )
face.load_char('A', FT_LOAD_COLOR )
slot = face.glyph._FT_GlyphSlot
if (face.glyph.format == FT_GLYPH_FORMAT_SVG):
document = ctypes.cast(slot.contents.other, FT_SVG_Document)
doc = ctypes.string_at(document.contents.svg_document, # not terminated
size=document.contents.svg_document_length)
d = skia.Data(doc)
# skia-python #194 - the raw c++ api actually has a (ptr, len, bool) method!
# Data() shouldn't be needed.
m = skia.MemoryStream(d)
h = skia.SVGDOM.MakeFromStream(m)
WIDTH, HEIGHT = 160, 160
size = skia.Size()
size.fHeight = WIDTH
size.fWidth = HEIGHT
h.setContainerSize(size)
surface = skia.Surface(WIDTH * 2, HEIGHT)
with surface as canvas:
canvas.translate(0,HEIGHT)
h.render(canvas)
canvas.translate(WIDTH/4,0)
h.render(canvas)
canvas.translate(WIDTH/4,0)
h.render(canvas)
canvas.translate(WIDTH/4,0)
h.render(canvas)
canvas.translate(WIDTH/4,0)
h.render(canvas)
canvas.translate(WIDTH/4,0)
h.render(canvas)
surface.flushAndSubmit()
image = surface.makeImageSnapshot()
image.save("ot-svg-draw-skia.png", skia.kPNG)
from PIL import Image
Image.open("ot-svg-draw-skia.png").show()
else:
print("Not SVG glyph.format")
|