Compare commits

...

80 Commits

Author SHA1 Message Date
Moazin Khatti f943af6490 Document `svg_hooks` property. 2019-08-26 01:17:15 +05:00
Moazin Khatti eb9a614011 Improve ot-svg callback hooks documentation 2019-08-26 01:17:15 +05:00
Moazin Khatti 67c108bc9c [svg] Fix some unused variable warnings. 2019-08-26 01:17:15 +05:00
Moazin Khatti b84ae3420a Minor doc and styling improvements. 2019-08-26 01:17:15 +05:00
Moazin Khatti 3325b42e91 [base,ot-svg] Minor fixes.
* src/svg/ftsvg.c (ft_svg_transform) Bug fix. Warning fix.

* src/base/ftglyph.c (ft_svg_glyph_transform) Warning fix.
2019-08-26 01:17:15 +05:00
Moazin Khatti 561364002a For a devel build, enable SVG support as well as default hooks. 2019-08-26 01:17:15 +05:00
Moazin Khatti 7d6ebe3a81 [ot-svg] Makes `rsvg_port.c' a part of the single build. 2019-08-26 01:17:15 +05:00
Moazin Khatti 4d24f52ead [sfnt,svg] Fix includes to allow a `multi' build. 2019-08-26 01:17:15 +05:00
Moazin Khatti cb2e775408 Adds `ttsvg' for tracing in ttsvg.c 2019-08-26 01:17:15 +05:00
Moazin Khatti 03f7b5a6b6 [ot-svg] Renames `svgtypes.c' to `svgtypes.h'.
Also adds an `ifndef' check to prevent loading multiple times.
2019-08-26 01:17:15 +05:00
Moazin Khatti 253d2bad97 [ot-svg] Properly indent module description. 2019-08-26 01:17:15 +05:00
Moazin Khatti e54fbbf283 [ot-svg] Bug fix. 2019-08-26 01:17:15 +05:00
Moazin Khatti b6f04b03e4 [ot-svg] Free pixmap buffer if error occurs while rendering. 2019-08-26 01:17:15 +05:00
Moazin Khatti 836c94e8d2 [ot-svg] Don't accept the hooks if value has been passed from an
env variable.
2019-08-26 01:17:14 +05:00
Moazin Khatti c492bf3f0a Handle cascaded transformations correctly.
We use homogeneous coordinates to properly calculate an equivalent
transformation correctly.
2019-08-26 01:17:14 +05:00
Moazin Khatti 3f6f939378 Adds transform support for OT-SVG glyphs. 2019-08-26 01:17:14 +05:00
Moazin Khatti 2727bba550 Formatting improvement. 2019-08-26 01:17:14 +05:00
Moazin Khatti cff4467f25 Minor doc improvement. 2019-08-26 01:17:14 +05:00
Moazin Khatti 22d7c8578f Minor name change.
`svgrender.h' -> `otsvg.h'
`FT_SVG_RENDER_H' -> `FT_OTSVG_H'
Since `svgrender.h' contains just the hooks and the SVG document
structure it's probably just better to name it something general
like `otsvg.h'.
2019-08-26 01:17:14 +05:00
Moazin Khatti 5f5a56a0cc Minor. Fixes a silly mistake. 2019-08-26 01:17:14 +05:00
Moazin Khatti c21c2b0e70 An old commit deleted a line by mistake. Fix that. 2019-08-26 01:17:14 +05:00
Moazin Khatti b122db0953 Fix TODOs. 2019-08-26 01:17:14 +05:00
Moazin Khatti 168a8f8fe0 Makes some helper functions `static'. 2019-08-26 01:17:14 +05:00
Moazin Khatti 705320b72d Check if the size has been properly set.
For TTF outlines this is already handled, however,
for traditional CFF outlines the check happens too
late. We need to check early.
2019-08-26 01:17:14 +05:00
Moazin Khatti fdb7d53ebf Fixes code warnings. 2019-08-26 01:17:14 +05:00
Moazin Khatti 74f80fba49 No need to call `FT_Load_Glyph' with `XX_NO_SCALE'.
We no longer need TTF/CFF outlines for SVG rendering.
2019-08-26 01:17:14 +05:00
Moazin Khatti a227395912 Remove the dependence on outlines. No longer needed. 2019-08-26 01:17:14 +05:00
Moazin Khatti dbcc809e7c relying on cairo recording surface for extents and preset bitmap at load time, work in progress 2019-08-26 01:17:14 +05:00
Moazin Khatti 398801e2c0 Revert "Performs basic checks to see if SVG data is valid or not."
This reverts commit e5dc1b65cdc7ea357118fddbdb4b00afc403f81c.
These aren't necessary.
2019-08-26 01:17:14 +05:00
Moazin Khatti 0e8e132bd7 Performs basic checks to see if SVG data is valid or not. 2019-08-26 01:17:14 +05:00
Moazin Khatti d7f6f8b16d Tracing implemented for OT-SVG code. 2019-08-26 01:17:14 +05:00
Moazin Khatti 2cef19641a Remove the TODO since I have implemented binary search. 2019-08-26 01:17:14 +05:00
Moazin Khatti faa495befc Remove the unused variable. 2019-08-26 01:17:14 +05:00
Moazin Khatti b85cc5ef0d For now resort to a simpler regular expresion.
We have to remove the system installation of FreeType
from the includes, the proper way is to write a regular
expression that removes the whole path. The last one
is buggy (it can remove other libs along with freetype)
so for now I am temporarily resorting to this one.
2019-08-26 01:17:14 +05:00
Moazin Khatti 3479e03cdb Added a new error `Invalid_SVG_Document'. 2019-08-26 01:17:14 +05:00
Moazin Khatti ba9e6f9d41 Implement binary search for SVG Document Lookup. 2019-08-26 01:17:14 +05:00
Moazin Khatti 6962986cf3 Created `Svg_doc' private struct.
Inside the SVG Document List, four fields exist. It's
better to create a struct to hold at one place instead
of 4 variables. Also created `compare_svg_doc' which
will be helpful in writing binary search later.
2019-08-26 01:17:14 +05:00
Moazin Khatti 2d13c5127c Add a comment there. That part can be confusing. 2019-08-26 01:17:14 +05:00
Moazin Khatti bb1b25e560 Make `ft_svg_renderer_class' dumb if OT-SVG
support is disabled.
2019-08-26 01:17:14 +05:00
Moazin Khatti 5e949729e3 Correct the prioritization of options. Clean code.
If `yes' is choosen but SVG library isn't found, exit
with error. If `auto' was choosen but the library wasn't
found, go with `no' NOT `no-default'. `no-default' should
be a separate option.
2019-08-26 01:17:14 +05:00
Moazin Khatti f86fe242d4 Improve `--with-svg' in the build system.
Added a `no-default' option that compiles SVG support
but keeps no default rendering port. Thus, the client
application must inject its own hooks.

* builds/unix/configure.raw: Changes in the build
system to support `no-default'.

* builds/unix/unix-cc.in: Add `COMPILE_SVG_PORT' var
to ultimately let the `rules.mk' in `svg' folder know
whether to build the port files or not.

* include/freetype/config/ftoption.h: Change the flag
`FT_CONFIG_OPTION_SVG_DEFAULT' to `*_DEFAULT_SVG' as
`sed' and `ftoption_set' has a problem with the older
version.

* src/svg/ftsvg.c: Ditto.

* src/svg/rules.mk: Compile the port only if
`COMPILE_SVG_PORT' is set.
2019-08-26 01:17:14 +05:00
Moazin Khatti 4025f1213e Add a `hooks_set' flag.
A flag is to be used to indicate whether hooks
have been set or not. In case the hooks haven't
been set, a `Missing_SVG_Hooks' error will be
thrown.
2019-08-26 01:17:14 +05:00
Moazin Khatti 246ac684e4 Plug in a default library. `librsvg' for now. 2019-08-26 01:17:14 +05:00
Moazin Khatti d86de4e9d4 Instead of individual properties. Just use one that
takes pointer to the hooks structure.
2019-08-26 01:17:14 +05:00
Moazin Khatti 1541091e76 Use `FT_Property_Set' to set the hooks. One less API function. 2019-08-26 01:17:14 +05:00
Moazin Khatti b6f2303338 Public interface should remain same whether
`FT_CONFIG_OPTION_SVG' is set or not.
2019-08-26 01:17:14 +05:00
Moazin Khatti 3b62e9dc9d Added `FT_CONFIG_OPTION_SVG'. 2019-08-26 01:17:07 +05:00
Moazin Khatti c25304fa34 Documentation formatting improvement. 2019-08-17 20:36:05 +05:00
Moazin Khatti c6a6859ad9 Better naming used. 2019-08-17 20:36:05 +05:00
Moazin Khatti bf1deae970 Forgot an `else', fix that. 2019-08-17 20:36:05 +05:00
Moazin Khatti fbdd9f9ba3 Memory allocation for `state' of renderer should be performed
on the SVG port side not the FT size. Minor doc fixes.
2019-08-17 20:36:05 +05:00
Moazin Khatti cf44c0cbdd Remove unnecessary code from `FT_Render_Glyph_Internal'. 2019-08-17 20:36:05 +05:00
Moazin Khatti 1f74524929 Let FT handle the memory management for rendering port's state
and the image buffer.

State has been moved inside the library structure. A new hook
function has been added to query the size needed for the state
structure and this allocation is performed by FT. Memory alloc.
for the image buffer is also being done by FT so that it can later
free it easily.

* include/freetype/svgrenderer.h: Small doc fixes. Addition of two
new hooks. `SVG_Lib_Get_State_Size' and `SVG_Lib_Get_Buffer_Size'.

* src/base/ftglyph.c (FT_Glyph_To_Bitmap): Small bug fix. Memory
was being initialized before library.

* src/base/ftobjs.c (FT_Set_Svg_Hooks): Adjust the code for new
hook functions.

* src/svg/ftsvg.c: Adjust the code for new hook functions. Perform
all memory allocations needed by the rendering port from FreeType
side.

* src/svg/svgtypes.c: Add the new hooks in the hook structure.
2019-08-17 20:36:05 +05:00
Moazin Khatti de44a3fda8 Store the rendering port's state in library.
Before this commit, the state of a rendering port was being
held globally. Now, it'll be stored in library->svg_renderer_state.
2019-08-17 20:36:05 +05:00
Moazin Khatti e028be97b8 Minor fixes. 2019-08-17 20:36:05 +05:00
Moazin Khatti d8202166c0 Add `start_glyph_id' and `end_glyph_id'.
These two fields are added to `FT_SvgGlyphRec' and
`FT_SVG_DocumentRec'. This is to allow the rendering port to create
a caching mechanism.
2019-08-17 20:36:05 +05:00
Moazin Khatti e48cf716f8 Add a `units_per_EM' field.
A field `units_per_EM' is added to `FT_SVG_DocumentRec' and
`FT_SvgGlyphRec'. This is needed because the renderer needs this
info to properly scale the SVGs if the viewbox width and height
differ from `face->units_per_EM'. Face object can't be accessed
because of the restrictions put by `FT_Glyph_To_Bitmap' thus this
has to be provided separately just like `metrics'.
2019-08-17 20:36:05 +05:00
Moazin Khatti 7275d6562f Do proper memory freeing to prevent leaks.
* include/freetype/internal/ftobjs.h: Create a new flag named
`FT_GLYPH_OWN_GZIP_SVG' to indicate that `svg_document' in
`slot->other' is GZIP compressed and has to be freed later.

* src/base/ftglyph.c: Minor styling.

* src/base/ftobjs.c: Add code to free memory that was previously
allocated for storing GZIP compressed SVG documents.

* src/sfnt/ttsvg.c: Set the `FT_GLYPH_OWN_GZIP_SVG' flag if the
document is GZIP compressed.
2019-08-17 20:36:05 +05:00
Moazin Khatti 22988063b0 Minor. Add documentation. 2019-08-17 20:36:05 +05:00
Moazin Khatti 1073e4cf5c * src/sfnt/ttsvg.c (tt_face_load_svg_doc): Minor fix. Don't return
immediately in case of Gzip compressed SVG documents.
2019-08-17 20:36:05 +05:00
Moazin Khatti 6a39dd0b16 Properly free memory of SVG document referenced in `slot->other'.
* include/freetype/freetype.h: Add `FT_FACE_FLAG_SVG' to indicate
the presence of an SVG table in the face.

* src/base/ftobjs.c (ft_glyphslot_init): Allocate memory for
`FT_SVG_Document' in `slot->other' if an SVG table exists in the
face.
(ft_glyphslot_clear): Clear `slot->other' only if the font doesn't
have an SVG table.
(ft_glyphslot_done): Free the memory at `slot->other' if the face
has an SVG table.

* src/base/ttsvg.c (tt_face_load_svg): Set `FT_FACE_FLAG_SVG'.
(tt_face_load_svg_doc): Don't allocate the memory.
2019-08-17 20:36:05 +05:00
Moazin Khatti 1e6cfffcb2 Enable FreeType memory debugger. 2019-08-17 20:36:05 +05:00
Moazin Khatti 41d34c8118 [cache] Consider `FT_GLYPH_FORMAT_SVG' a valid format. 2019-08-17 20:36:05 +05:00
Moazin Khatti d1a0615f00 Minor changes.
* src/base/ftobjs.c (FT_Load_Glyph): Use the recrusive call with
`FT_LOAD_NO_SCALE' so that the loaded data is unscaled.

* src/base/ftobjs.c (FT_Render_Glyph_Internal): Change the format
to bitmap once an SVG glyph is successfully rendered.

* src/sfnt/ttsvg.c (tt_face_load_svg_doc): Make sure metrics are
grabbed. Scale `horiAdvance' and `vertAdvance' properly and
convert them to 26.6 format.
2019-08-17 20:36:05 +05:00
Moazin Khatti 6bf9ade45c Adds support for SVG glyphs to Glyph Management API. 2019-08-17 20:36:05 +05:00
Moazin Khatti 61b1f0b73c Make sure `FT_Set_Svg_Hooks' is exported properly. 2019-08-17 20:36:05 +05:00
Moazin Khatti 294a7ebee2 Adds size information to `FT_SVG_DocumentRec'.
This is necessary because the document itself contains no
sizing information. Outline glyphs encapsulate the sizing
information in the outlines by scaling them. That is not
possible here. One could access them from the face object
reference inside a glyph slot, but when the function
`FT_Glyph_To_Bitmap' creates a dummy slot it can not put
a face object reference in it. Thus, it's better to store
the size information here.
2019-08-17 20:36:05 +05:00
Moazin Khatti 0bf6444911 [ot-svg] Create an SVG Document structure for use in `other' field
of `FT_GlyphSlot'.
2019-08-17 20:36:05 +05:00
Moazin Khatti 877736d057 Removes trailing white spaces. 2019-08-17 20:36:05 +05:00
Moazin Khatti f8eae8a824 Reverts the changes made in the structure of `TT_GlyphSlot' 2019-08-17 20:36:05 +05:00
Moazin Khatti 479c76c867 [ot-svg] Silly mistake fix.
Instead of an `FT_Library' instance, `FT_Module' is supposed
to be passed.
2019-08-17 20:36:05 +05:00
Moazin Khatti 9a55001454 Minor. Better documentation. Adds TODOs for letter. 2019-08-17 20:36:05 +05:00
Moazin Khatti 4d59b8535e [ot-svg] Creates hooks mechanism in SVG Renderer.
* include/freetype/config/ftheader.h: New macro `FT_SVG_RENDERER_H'
for `freetype/svgrenderer.h'.

* include/freetype/svgrenderer.h: New file to store SVG specific
function types, SVG interface and `FT_Set_Svg_Hooks'.

* src/base/ftobjs.c: Adds implementation of `FT_Set_Svg_Hooks'.

* src/svg/ftsvg.c: Creates `svg_renderer_interface'.

* src/svg/svgtypes.c: Moves hook function types to
`FT_SVG_RENDERER_H'. Adds a hook for svg rendering. Temporary.
2019-08-17 20:36:05 +05:00
Moazin Khatti f1db18a464 Barebones of an SVG rendering module and making it part of the build system 2019-08-17 20:36:05 +05:00
Moazin Khatti db972c0568 Support OT-SVG fonts with CFF outlines 2019-08-17 20:36:05 +05:00
Moazin Khatti b9734fd870 Very crude way to handle SVG data with only TTF outlined OT fonts. Gonna revert soon. 2019-08-17 20:36:05 +05:00
Moazin Khatti 82f8102da6 Added FT_GLYPH_FORMAT_SVG 2019-08-17 20:36:05 +05:00
Moazin Khatti 9b7c3d1df9 Created Svg type and the load/free funcs inside sfnt interface 2019-08-17 20:36:05 +05:00
Moazin Khatti 0729a65165 Added the SVG tag 2019-08-17 20:36:05 +05:00
Moazin Khatti 311a253d4b turned on trace mode and added tags file in gitignore 2019-08-17 20:36:05 +05:00
37 changed files with 1877 additions and 15 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
config.mk
objs/vc2010/
build
tags

View File

@ -130,8 +130,9 @@ ifdef DEVEL_DIR
# We assume that all library dependencies for FreeType are fulfilled for a
# development build, so we directly access the necessary include directory
# information using `pkg-config'.
INCLUDE_FLAGS += $(shell pkg-config --cflags libpng \
harfbuzz )
INCLUDE_FLAGS += $(shell pkg-config --cflags libpng \
harfbuzz \
librsvg-2.0 \)
endif

View File

@ -542,7 +542,44 @@ if test x"$with_harfbuzz" = xyes -a "$have_harfbuzz" = no; then
AC_MSG_ERROR([harfbuzz support requested but library not found])
fi
# OT-SVG checks
# Librsvg is the default for now!
AC_ARG_WITH([svg],
[AS_HELP_STRING([--with-svg=@<:@yes|no|auto|no-default@:>@],
[support OpenType SVG fonts @<:@default=auto@:>@])],
[], [with_svg=auto])
have_librsvg=no
if test x"$with_svg" = xyes -o x"$with_svg" = xauto; then
librsvg_pkg="librsvg-2.0 >= 2.40.0"
have_librsvg_pkg=no
if test x"$LIBRSVG_CFLAGS" = x -a x"$LIBRSVG_LIBS" = x; then
PKG_CHECK_EXISTS([$librsvg_pkg], [have_librsvg_pkg=yes])
fi
PKG_CHECK_MODULES([LIBRSVG], [$librsvg_pkg],
[have_librsvg="yes (pkg-config)"], [:])
if test $have_librsvg_pkg = yes; then
# we have librsvg pkg-config file
librsvg_reqpriv="$librsvg_pkg"
librsvg_libspriv=
librsvg_libsstaticconf=`$PKG_CONFIG --static --libs "$librsvg_pkg"`
else
librsvg_reqpriv=
if test "$have_librsvg" != no; then
# LIBRSVG_CFLAGS and LIBRSVG_LIBS are set by the user
librsvg_libspriv="$LIBRSVG_LIBS"
librsvg_libsstaticconf="$LIBRSVG_LIBS"
have_librsvg="yes (LIBRSVG_CFLAGS and LIBRSVG_LIBS)"
fi
fi
fi
if test x"$with_svg" = xyes -a x"$have_librsvg" = xno; then
AC_MSG_ERROR([SVG support requested but library not found])
fi
# check for librt
#
# We need `clock_gettime' for the `ftbench' demo program.
@ -992,7 +1029,8 @@ fi
REQUIRES_PRIVATE="$zlib_reqpriv, \
$bzip2_reqpriv, \
$libpng_reqpriv, \
$harfbuzz_reqpriv"
$harfbuzz_reqpriv, \
$librsvg_reqpriv"
# beautify
REQUIRES_PRIVATE=`echo "$REQUIRES_PRIVATE" \
| sed -e 's/^ *//' \
@ -1007,7 +1045,8 @@ LIBS_PRIVATE="$zlib_libspriv \
$bzip2_libspriv \
$libpng_libspriv \
$harfbuzz_libspriv \
$ft2_extra_libs"
$ft2_extra_libs \
$librsvg_libspriv"
# beautify
LIBS_PRIVATE=`echo "$LIBS_PRIVATE" \
| sed -e 's/^ *//' \
@ -1019,7 +1058,9 @@ LIBSSTATIC_CONFIG="-lfreetype \
$bzip2_libsstaticconf \
$libpng_libsstaticconf \
$harfbuzz_libsstaticconf \
$ft2_extra_libs"
$ft2_extra_libs \
$librsvg_libsstaticconf"
# remove -L/usr/lib and -L/usr/lib64 since `freetype-config' adds them later
# on if necessary; also beautify
LIBSSTATIC_CONFIG=`echo "$LIBSSTATIC_CONFIG" \
@ -1084,6 +1125,24 @@ else
ftoption_unset FT_CONFIG_OPTION_USE_HARFBUZZ
fi
if test "$with_svg" = no-default; then
ftoption_set FT_CONFIG_OPTION_SVG
ftoption_unset FT_CONFIG_OPTION_DEFAULT_SVG
have_librsvg="no-default"
elif test "$with_svg" = no; then
ftoption_unset FT_CONFIG_OPTION_SVG
ftoption_unset FT_CONFIG_OPTION_DEFAULT_SVG
elif test "$with_svg" = auto -a "$have_librsvg" = no; then
ftoption_unset FT_CONFIG_OPTION_SVG
ftoption_unset FT_CONFIG_OPTION_DEFAULT_SVG
else
LIBRSVG_CFLAGS=$(echo $LIBRSVG_CFLAGS | sed -e 's/freetype2//g')
CFLAGS="$CFLAGS $LIBRSVG_CFLAGS"
LDFLAGS="$LDFLAGS $LIBRSVG_LIBS"
ftoption_set FT_CONFIG_OPTION_SVG
ftoption_set FT_CONFIG_OPTION_DEFAULT_SVG
fi
AC_SUBST([CFLAGS])
AC_SUBST([LDFLAGS])
@ -1129,6 +1188,7 @@ Library configuration:
bzip2: $have_bzip2
libpng: $have_libpng
harfbuzz: $have_harfbuzz
svg support: $have_librsvg
])
# Warn if docwriter is not installed

View File

@ -493,6 +493,19 @@ FT_BEGIN_HEADER
#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
/**************************************************************************
*
* OpenType SVG Glyph Support
*
* If `FT_CONFIG_OPTION_SVG` is set, OpenType SVG glyphs will be
* supported.
* If `FT_CONFIG_OPTION_DEFAULT_SVG` is also set, a default library will
* also be integrated so no external hooks will be necessary.
*/
#define FT_CONFIG_OPTION_SVG
#define FT_CONFIG_OPTION_DEFAULT_SVG
/**************************************************************************
*
* Error Strings

View File

@ -547,6 +547,19 @@
#define FT_BITMAP_H <freetype/ftbitmap.h>
/**************************************************************************
*
* @macro:
* FT_OTSVG_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API of OT-SVG support related things.
*
*/
#define FT_OTSVG_H <freetype/otsvg.h>
/**************************************************************************
*
* @macro:

View File

@ -414,7 +414,7 @@ FT_BEGIN_HEADER
* them for certain configurations only.
*/
/* #define FT_DEBUG_LEVEL_ERROR */
/* #define FT_DEBUG_LEVEL_TRACE */
#define FT_DEBUG_LEVEL_TRACE
/**************************************************************************
@ -473,7 +473,7 @@ FT_BEGIN_HEADER
* Do not `#undef` this macro here since the build system might define it
* for certain configurations only.
*/
/* #define FT_DEBUG_MEMORY */
#define FT_DEBUG_MEMORY
/**************************************************************************
@ -493,6 +493,19 @@ FT_BEGIN_HEADER
#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
/**************************************************************************
*
* OpenType SVG Glyph Support
*
* If `FT_CONFIG_OPTION_SVG` is set, OpenType SVG glyphs will be
* supported.
* If `FT_CONFIG_OPTION_DEFAULT_SVG` is also set, a default library will
* also be integrated so no external hooks will be necessary.
*/
#define FT_CONFIG_OPTION_SVG
/* #define FT_CONFIG_OPTION_DEFAULT_SVG */
/**************************************************************************
*
* Error Strings

View File

@ -141,6 +141,7 @@ FT_BEGIN_HEADER
* FT_FACE_FLAG_GLYPH_NAMES
* FT_FACE_FLAG_EXTERNAL_STREAM
* FT_FACE_FLAG_HINTER
* FT_FACE_FLAG_SVG
*
* FT_HAS_HORIZONTAL
* FT_HAS_VERTICAL
@ -1206,6 +1207,9 @@ FT_BEGIN_HEADER
* altered with @FT_Set_MM_Design_Coordinates,
* @FT_Set_Var_Design_Coordinates, or @FT_Set_Var_Blend_Coordinates.
* This flag is unset by a call to @FT_Set_Named_Instance.
*
* FT_FACE_FLAG_SVG ::
* Set if the current face has an SVG table.
*/
#define FT_FACE_FLAG_SCALABLE ( 1L << 0 )
#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 )
@ -1223,6 +1227,7 @@ FT_BEGIN_HEADER
#define FT_FACE_FLAG_TRICKY ( 1L << 13 )
#define FT_FACE_FLAG_COLOR ( 1L << 14 )
#define FT_FACE_FLAG_VARIATION ( 1L << 15 )
#define FT_FACE_FLAG_SVG ( 1L << 16 )
/**************************************************************************

View File

@ -619,6 +619,46 @@ FT_BEGIN_HEADER
*/
/**************************************************************************
*
* @property:
* svg_hooks
*
* @description:
* OT-SVG glyphs are rendererd with the use of some callback hooks to an
* external SVG rendering library. OT-SVG glyphs support can be enabled
* by compiling FreeType with `FT_CONFIG_OPTION_SVG`. The hooks can be
* stored in an @SVG_RendererHooks structure, which is then passed as the
* value of `svg_hooks` property. See the example. We also provide
* default hooks which can be enabled by compiling with
* `FT_CONFIG_OPTION_DEFAULT_SVG`. Then, nothing needs to be set from
* the user side, unless the user wants to use some other library.
*
* @note:
* This property can only be set via @FT_Property_Set.
*
* @example:
* ```
* FT_Library library;
* SVG_RendererHooks hooks;
*
*
* FT_Init_FreeType( &library );
*
* hooks.init_svg = (SVG_Lib_Init_Func)foo_port_init;
* hooks.free_svg = (SVG_Lib_Free_Func)foo_port_free;
* hooks.render_svg = (SVG_Lib_Render_Func)foo_port_render;
* hooks.preset_slot = (SVG_Lib_Preset_Slot_Func)foo_port_preset_slot;
*
* FT_Property_Set( library, "ot-svg", "svg_hooks", &hooks );
*
* ```
*
* @since:
* 2.11
*/
/**************************************************************************
*
* @enum:

View File

@ -101,6 +101,8 @@
"too many hints" )
FT_ERRORDEF_( Invalid_Pixel_Size, 0x17,
"invalid pixel size" )
FT_ERRORDEF_( Invalid_SVG_Document, 0x18,
"invalid SVG document" )
/* handle errors */
@ -234,6 +236,8 @@
"found FDEF or IDEF opcode in glyf bytecode" )
FT_ERRORDEF_( Missing_Bitmap, 0x9D,
"missing bitmap in strike" )
FT_ERRORDEF_( Missing_SVG_Hooks, 0x9E,
"hooks have not been set" )
/* CFF, CID, and Type 1 errors */

View File

@ -223,6 +223,87 @@ FT_BEGIN_HEADER
} FT_OutlineGlyphRec;
/**************************************************************************
*
* @type:
* FT_SvgGlyph
*
* @description:
* A handle to an object used to model an SVG glyph image. This is a
* sub-class of @FT_Glyph, and a pointer to @FT_SvgGlyphRec.
*/
typedef struct FT_SvgGlyphRec_* FT_SvgGlyph;
/**************************************************************************
*
* @struct:
* FT_SvgGlyphRec
*
* @description:
* A structure used for OT-SVG glyph images. This really is a 'sub-class'
* of @FT_GlyphRec.
*
* @fields:
* root ::
* The root @FT_GlyphRec fields.
*
* svg_document ::
* A pointer to the SVG document.
*
* svg_document_length ::
* The length of `svg_document`.
*
* glyph_index ::
* The index of the glyph to be rendered.
*
* metrics ::
* A metrics object storing the size information.
*
* units_per_EM ::
* The size of the EM square.
*
* start_glyph_id ::
* The first glyph ID in the glyph range is covered by this document.
*
* end_glyph_id ::
* The last glyph ID in the glyph range is covered by this document.
*
* transform ::
* A 2x2 transformation matrix to apply on the glyph while rendering it.
*
* delta ::
* Translation to apply on the glyph while rendering.
*
* @note:
* `metrics` and `units_per_EM` might look like repetitions since both
* fields are stored in face objects. However, the Glyph Management API
* requires an `FT_Glyph` to store all the information that completely
* describes a glyph. Outline glyphs are themselves scaled thus they
* don't need this information. However, SVG documents do. The field of
* `units_per_EM` is needed because the SVG is to be scaled in case its
* viewbox size differs from `units_per_EM`. For more info, refer to
* the section _Coordinate Systems and Glyph Metrics_ of the OpenType
* SVG specs. The `transform` and `delta` are stored here because for an
* SVG document, there's no way to apply a transformation without parsing
* it. Thus, we just store the transform and later the renderer can apply
* it while rendering.
*/
typedef struct FT_SvgGlyphRec_
{
FT_GlyphRec root;
FT_Byte* svg_document;
FT_ULong svg_document_length;
FT_UInt glyph_index;
FT_Size_Metrics metrics;
FT_UShort units_per_EM;
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
FT_Matrix transform;
FT_Vector delta;
} FT_SvgGlyphRec;
/**************************************************************************
*
* @function:

View File

@ -732,6 +732,10 @@ FT_BEGIN_HEADER
* contours. Some Type~1 fonts, like those in the Hershey family,
* contain glyphs in this format. These are described as @FT_Outline,
* but FreeType isn't currently capable of rendering them correctly.
*
* FT_GLYPH_FORMAT_SVG ::
* The glyph is represented by an SVG documents in the SVG table.
*
*/
typedef enum FT_Glyph_Format_
{
@ -740,7 +744,8 @@ FT_BEGIN_HEADER
FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ),
FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ),
FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ),
FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' )
FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' ),
FT_IMAGE_TAG( FT_GLYPH_FORMAT_SVG, 's', 'v', 'g', ' ' )
} FT_Glyph_Format;
@ -752,6 +757,7 @@ FT_BEGIN_HEADER
#define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP
#define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE
#define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER
#define ft_glyph_format_svg FT_GLYPH_FORMAT_SVG
/*************************************************************************/

View File

@ -418,7 +418,8 @@ FT_BEGIN_HEADER
* initializing the glyph slot.
*/
#define FT_GLYPH_OWN_BITMAP 0x1U
#define FT_GLYPH_OWN_BITMAP 0x1U
#define FT_GLYPH_OWN_GZIP_SVG 0x2U
typedef struct FT_Slot_InternalRec_
{
@ -889,6 +890,10 @@ FT_BEGIN_HEADER
* created. @FT_Reference_Library increments this counter, and
* @FT_Done_Library only destroys a library if the counter is~1,
* otherwise it simply decrements it.
*
* svg_renderer_state ::
* A pointer to a state object that will have the state of the SVG
* Renderer. This will be totally managed by the renderer.
*/
typedef struct FT_LibraryRec_
{
@ -916,6 +921,10 @@ FT_BEGIN_HEADER
FT_Int refcount;
#ifdef FT_CONFIG_OPTION_SVG
void* svg_renderer_state;
#endif
} FT_LibraryRec;

View File

@ -39,6 +39,7 @@ FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */
FT_TRACE_DEF( psprops ) /* PS driver properties (ftpsprop.c) */
FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */
FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */
FT_TRACE_DEF( otsvg ) /* ot-svg renderer (ftsvg.c) */
FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */
FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */
@ -53,6 +54,7 @@ FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */
FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */
FT_TRACE_DEF( ttcolr ) /* glyph layer table (ttcolr.c) */
FT_TRACE_DEF( ttcpal ) /* color palette table (ttcpal.c) */
FT_TRACE_DEF( ttsvg ) /* ot-svg glyph table (ttsvg.c) */
FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */
FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */
FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */

View File

@ -37,6 +37,7 @@
#define FT_INTERNAL_SERVICE_H <freetype/internal/ftserv.h>
#define FT_INTERNAL_RFORK_H <freetype/internal/ftrfork.h>
#define FT_INTERNAL_VALIDATE_H <freetype/internal/ftvalid.h>
#define FT_INTERNAL_SVG_INTERFACE_H <freetype/internal/svginterface.h>
#define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h>
#define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h>

View File

@ -312,6 +312,31 @@ FT_BEGIN_HEADER
TT_SBit_MetricsRec *ametrics );
/**************************************************************************
*
* @functype:
* TT_Load_Svg_Doc_Func
*
* @description:
* Scan the SVG document list to find the document containing the glyph
* that has the id "glyph<glyph_index>".
*
* @input:
* glyph ::
* The glyph slot from which pointers to SVG document list will be
* grabbed. The results will be stored back in the slot too.
*
* glyph_index ::
* The index of the glyph that is to be looked up.
*
* @return:
* FreeType error code. 0 means success.
*/
typedef FT_Error
(*TT_Load_Svg_Doc_Func)( FT_GlyphSlot glyph,
FT_UInt glyph_index );
/**************************************************************************
*
* @functype:
@ -778,6 +803,11 @@ FT_BEGIN_HEADER
TT_Get_Name_Func get_name;
TT_Get_Name_ID_Func get_name_id;
/* Open Type SVG Support */
TT_Load_Table_Func load_svg;
TT_Free_Table_Func free_svg;
TT_Load_Svg_Doc_Func load_svg_doc;
} SFNT_Interface;
@ -824,7 +854,10 @@ FT_BEGIN_HEADER
colr_blend_, \
get_metrics_, \
get_name_, \
get_name_id_ ) \
get_name_id_, \
load_svg_, \
free_svg_, \
load_svg_doc_ ) \
static const SFNT_Interface class_ = \
{ \
goto_table_, \
@ -864,7 +897,10 @@ FT_BEGIN_HEADER
colr_blend_, \
get_metrics_, \
get_name_, \
get_name_id_ \
get_name_id_, \
load_svg_, \
free_svg_, \
load_svg_doc_ \
};

View File

@ -0,0 +1,43 @@
/****************************************************************************
*
* svginterface.h
*
* Exposes the interface of ot-svg module
*
* Copyright (C) 1996-2019 by
* David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef SVGINTERFACE_H
#define SVGINTERFACE_H
#include <ft2build.h>
#include FT_OTSVG_H
FT_BEGIN_HEADER
typedef FT_Error
(*Preset_Bitmap_Func)( FT_Module module,
FT_GlyphSlot slot,
FT_Bool cache );
typedef struct SVG_Interface_
{
Preset_Bitmap_Func preset_slot;
} SVG_Interface;
typedef SVG_Interface* SVG_Service;
FT_END_HEADER
#endif

View File

@ -1645,6 +1645,9 @@ FT_BEGIN_HEADER
void* cpal;
void* colr;
/* OpenType SVG Glyph Support */
void* svg;
} TT_FaceRec;

232
include/freetype/otsvg.h Normal file
View File

@ -0,0 +1,232 @@
/****************************************************************************
*
* otsvg.h
*
* Interface for OT-SVG support related things (specification).
*
* Copyright (C) 2004-2019 by
* David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTSVG_RENDERER_H_
#define FTSVG_RENDERER_H_
#include <ft2build.h>
#include FT_FREETYPE_H
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @functype:
* SVG_Lib_Init_Func
*
* @description:
* A callback which is called when the first OT-SVG glyph is rendered in
* the lifetime of an @FT_Library object. The callback should perform all
* sorts of initializations that the SVG rendering library needs such as
* allocating memory for `svg_renderer_state` of @FT_LibraryRec.
*
* @input:
* library ::
* An instance of @FT_Library. It's passed to give the callbacks access
* to `svg_renderer_state` of @FT_LibraryRec.
*
* @return:
* FreeType error code. 0 means success.
*/
typedef FT_Error
(*SVG_Lib_Init_Func)( FT_Library library );
/**************************************************************************
*
* @functype:
* SVG_Lib_Free_Func
*
* @description:
* A callback which is called when the `ot-svg` module is being freed.
* It is only called only if the init hook was called earlier. So, if no
* OT-SVG glyph is rendered, neither the init hook is called nor the free
* hook.
*
* @input:
* library ::
* An instance of @FT_Library. It's passed to give the callbacks access
* to `svg_renderer_state` of @FT_LibraryRec.
*/
typedef void
(*SVG_Lib_Free_Func)( FT_Library library );
/**************************************************************************
*
* @functype:
* SVG_Lib_Render_Func
*
* @description:
* A callback which is called to render an OT-SVG glyph. This callback
* hook is called right after the preset hook has been called with
* `cache` set to `TRUE`. The data necessary to render is available
* through the handle @FT_SVG_Document which is set in `other` field of
* @FT_GlyphSlotRec.
*
* @input:
* slot ::
* The slot to render.
*
* @return:
* FreeType error code. 0 means success.
*/
typedef FT_Error
(*SVG_Lib_Render_Func)( FT_GlyphSlot slot );
/**************************************************************************
*
* @functype:
* SVG_Lib_Preset_Slot_Func
*
* @description:
* A callback which is called to preset the glyphslot. It is called from
* two places.
*
* 1. When `FT_Load_Glyph` needs to preset the glyphslot.
* 2. Right before the `ot-svg` module calls the render callback hook.
*
* When it is the former, the argument `cache` is set to `FALSE`. When it
* is the latter, the argument `cache` is set to `TRUE`. This distinction
* has been made because while presetting a glyphslot many calculations
* are needed and later the render callback hook needs the same
* calculations, thus, if `cache` is `TRUE`, the hook might _cache_ these
* calculations in `svg_renderer_state` of @FT_LibraryRec.
*
* @input:
* slot ::
* The glyph slot which has the SVG document loaded.
*
* cache ::
* See description.
*
* @return:
* FreeType error code. 0 means success.
*/
typedef FT_Error
(*SVG_Lib_Preset_Slot_Func)( FT_GlyphSlot slot, FT_Bool cache);
/**************************************************************************
*
* @struct:
* SVG_RendererHooks
*
* @description:
* A structure that stores the four hooks needed to render OT-SVG glyphs
* properly. The structure is publicly used to set the hooks via driver
* properties.
*
* @fields:
* init_svg ::
* The initialization hook.
*
* free_svg ::
* The cleanup hook.
*
* render_hook ::
* The render hook.
*
* preset_slot ::
* The preset hook.
*/
typedef struct SVG_RendererHooks_
{
SVG_Lib_Init_Func init_svg;
SVG_Lib_Free_Func free_svg;
SVG_Lib_Render_Func render_svg;
SVG_Lib_Preset_Slot_Func preset_slot;
} SVG_RendererHooks;
/**************************************************************************
*
* @struct:
* FT_SVG_DocumentRec_
*
* @description:
* A structure that models one SVG document.
*
* @fields:
* svg_document ::
* A pointer to the SVG document.
*
* svg_document_length ::
* The length of `svg_document`.
*
* metrics ::
* A metrics object storing the size information.
*
* units_per_EM ::
* The size of the EM square.
*
* start_glyph_id ::
* The first glyph ID in the glyph range is covered by this document.
*
* end_glyph_id ::
* The last glyph ID in the glyph range is covered by this document.
*
* transform ::
* A 2x2 transformation matrix to apply on the glyph while rendering it.
*
* delta ::
* Translation to apply on the glyph while rendering.
*
* @note:
* `metrics` and `units_per_EM` might look like repetitions since both
* fields are stored in face object, but they are not; When the slot is
* passed down to a renderer, the renderer can only access the `metrics`
* and `units_per_EM` by `slot->face`. However, when `FT_Glyph_To_Bitmap`
* sets up a dummy object, it has no way to set a `face` object. Thus,
* metrics information and units_per_EM (which is necessary for OT-SVG)
* has to be stored separately.
*/
typedef struct FT_SVG_DocumentRec_
{
FT_Byte* svg_document;
FT_ULong svg_document_length;
FT_Size_Metrics metrics;
FT_UShort units_per_EM;
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
FT_Matrix transform;
FT_Vector delta;
} FT_SVG_DocumentRec;
/**************************************************************************
*
* @type:
* FT_SVG_Document
*
* @description:
* A handle to a FT_SVG_DocumentRec object.
*/
typedef struct FT_SVG_DocumentRec_* FT_SVG_Document;
FT_END_HEADER
#endif

View File

@ -96,6 +96,7 @@ FT_BEGIN_HEADER
#define TTAG_sbix FT_MAKE_TAG( 's', 'b', 'i', 'x' )
#define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' )
#define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' )
#define TTAG_SVG FT_MAKE_TAG( 'S', 'V', 'G', ' ' )
#define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' )
#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' )
#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' )

View File

@ -99,6 +99,9 @@ RASTER_MODULES += raster
# Anti-aliasing rasterizer.
RASTER_MODULES += smooth
# OT-SVG
RASTER_MODULES += svg
####
#### auxiliary modules

View File

@ -35,6 +35,7 @@
#include FT_OUTLINE_H
#include FT_BITMAP_H
#include FT_INTERNAL_OBJECTS_H
#include FT_OTSVG_H
/**************************************************************************
@ -275,6 +276,214 @@
ft_outline_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */
)
#ifdef FT_CONFIG_OPTION_SVG
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** FT_SvgGlyph support ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
FT_CALLBACK_DEF( FT_Error )
ft_svg_glyph_init( FT_Glyph svg_glyph,
FT_GlyphSlot slot )
{
FT_ULong doc_length;
FT_SVG_Document document;
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
FT_Error error = FT_Err_Ok;
FT_Memory memory = FT_GLYPH( glyph )->library->memory;
if ( slot->format != FT_GLYPH_FORMAT_SVG )
{
error = FT_THROW( Invalid_Glyph_Format );
goto Exit;
}
if ( slot->other == NULL )
{
error = FT_THROW( Invalid_Slot_Handle );
goto Exit;
}
document = (FT_SVG_Document)slot->other;
if ( document->svg_document_length == 0 )
{
error = FT_THROW( Invalid_Slot_Handle );
goto Exit;
}
/* allocate a new document */
doc_length = document->svg_document_length;
glyph->svg_document = memory->alloc( memory, doc_length );
glyph->svg_document_length = doc_length;
glyph->glyph_index = slot->glyph_index;
glyph->metrics = document->metrics;
glyph->units_per_EM = document->units_per_EM;
glyph->start_glyph_id = document->start_glyph_id;
glyph->end_glyph_id = document->end_glyph_id;
glyph->transform = document->transform;
glyph->delta = document->delta;
/* copy the document into glyph */
FT_MEM_COPY( glyph->svg_document, document->svg_document, doc_length );
Exit:
return error;
}
FT_CALLBACK_DEF( void )
ft_svg_glyph_done( FT_Glyph svg_glyph )
{
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
FT_Memory memory = svg_glyph->library->memory;
/* just free the memory */
memory->free( memory, glyph->svg_document );
}
FT_CALLBACK_DEF( FT_Error )
ft_svg_glyph_copy( FT_Glyph svg_source,
FT_Glyph svg_target )
{
FT_SvgGlyph source = (FT_SvgGlyph)svg_source;
FT_SvgGlyph target = (FT_SvgGlyph)svg_target;
FT_Error error = FT_Err_Ok;
FT_Memory memory = FT_GLYPH( source )->library->memory;
if ( svg_source->format != FT_GLYPH_FORMAT_SVG )
{
error = FT_THROW( Invalid_Glyph_Format );
return error;
}
if ( source->svg_document_length == 0 )
{
error = FT_THROW( Invalid_Slot_Handle );
return error;
}
target->glyph_index = source->glyph_index;
target->svg_document_length = source->svg_document_length;
target->metrics = source->metrics;
target->units_per_EM = source->units_per_EM;
target->start_glyph_id = source->start_glyph_id;
target->end_glyph_id = source->end_glyph_id;
target->transform = source->transform;
target->delta = source->delta;
/* allocate space for the svg document */
target->svg_document = memory->alloc( memory,
target->svg_document_length );
/* copy the stuff */
FT_MEM_COPY( target->svg_document,
source->svg_document,
target->svg_document_length );
return error;
}
FT_CALLBACK_DEF( void )
ft_svg_glyph_transform( FT_Glyph svg_glyph,
const FT_Matrix* _matrix,
const FT_Vector* _delta )
{
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
FT_Matrix* matrix = (FT_Matrix*)_matrix;
FT_Vector* delta = (FT_Vector*)_delta;
FT_Matrix tmp_matrix;
FT_Vector tmp_delta;
FT_Matrix a, b;
FT_Pos x, y;
if ( !matrix )
{
tmp_matrix.xx = 0x10000;
tmp_matrix.xy = 0;
tmp_matrix.yx = 0;
tmp_matrix.yy = 0x10000;
matrix = &tmp_matrix;
}
if ( !delta )
{
tmp_delta.x = 0;
tmp_delta.y = 0;
delta = &tmp_delta;
}
a = glyph->transform;
b = *matrix;
FT_Matrix_Multiply( &b, &a );
x = ADD_LONG(ADD_LONG(
FT_MulFix(matrix->xx, glyph->delta.x),
FT_MulFix(matrix->xy, glyph->delta.y)),
delta->x);
y = ADD_LONG(ADD_LONG(
FT_MulFix(matrix->yx, glyph->delta.x),
FT_MulFix(matrix->yy, glyph->delta.y)),
delta->y);
glyph->delta.x = x;
glyph->delta.y = y;
glyph->transform = a;
}
FT_CALLBACK_DEF( FT_Error )
ft_svg_glyph_prepare( FT_Glyph svg_glyph,
FT_GlyphSlot slot )
{
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
FT_Error error = FT_Err_Ok;
FT_Memory memory = svg_glyph->library->memory;
FT_SVG_Document document;
if ( FT_NEW( document ) )
return error;
document->svg_document = glyph->svg_document;
document->svg_document_length = glyph->svg_document_length;
document->metrics = glyph->metrics;
document->units_per_EM = glyph->units_per_EM;
document->start_glyph_id = glyph->start_glyph_id;
document->end_glyph_id = glyph->end_glyph_id;
document->transform = glyph->transform;
document->delta = glyph->delta;
slot->format = FT_GLYPH_FORMAT_SVG;
slot->glyph_index = glyph->glyph_index;
slot->other = document;
return error;
}
FT_DEFINE_GLYPH(
ft_svg_glyph_class,
sizeof ( FT_SvgGlyphRec ),
FT_GLYPH_FORMAT_SVG,
ft_svg_glyph_init, /* FT_Glyph_InitFunc glyph_init */
ft_svg_glyph_done, /* FT_Glyph_DoneFunc glyph_done */
ft_svg_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */
ft_svg_glyph_transform, /* FT_Glyph_TransformFunc glyph_transform */
NULL, /* FT_Glyph_GetBBoxFunc glyph_bbox */
ft_svg_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */
)
#endif
/*************************************************************************/
/*************************************************************************/
@ -376,6 +585,12 @@
else if ( format == FT_GLYPH_FORMAT_OUTLINE )
clazz = &ft_outline_glyph_class;
#ifdef FT_CONFIG_OPTION_SVG
/* if it is a SVG glyph */
else if ( format == FT_GLYPH_FORMAT_SVG )
clazz = &ft_svg_glyph_class;
#endif
else
{
/* try to find a renderer that supports the glyph image format */
@ -592,7 +807,16 @@
/* prepare dummy slot for rendering */
error = clazz->glyph_prepare( glyph, &dummy );
if ( !error )
{
error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
#ifdef FT_CONFIG_OPTION_SVG
if ( clazz == &ft_svg_glyph_class )
{
FT_Memory memory = library->memory;
FT_FREE( dummy.other );
}
#endif
}
#if 1
if ( !destroy && origin )

View File

@ -28,6 +28,7 @@
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */
#include FT_INTERNAL_POSTSCRIPT_AUX_H /* for PS_Driver */
#include FT_INTERNAL_SVG_INTERFACE_H
#include FT_TRUETYPE_TABLES_H
#include FT_TRUETYPE_TAGS_H
@ -40,6 +41,7 @@
#include FT_SERVICE_TT_CMAP_H
#include FT_SERVICE_KERNING_H
#include FT_SERVICE_TRUETYPE_ENGINE_H
#include FT_OTSVG_H
#include FT_DRIVER_H
@ -317,6 +319,17 @@
if ( !error && clazz->init_slot )
error = clazz->init_slot( slot );
#ifdef FT_CONFIG_OPTION_SVG
/* check if SVG table exists allocate the space in slot->other */
if ( slot->face->face_flags & FT_FACE_FLAG_SVG )
{
FT_SVG_Document document;
if ( FT_NEW( document ) )
goto Exit;
slot->other = document;
}
#endif
Exit:
return error;
}
@ -351,6 +364,7 @@
{
FT_Outline* outline = &slot->outline;
FT_Bitmap* bitmap = &slot->bitmap;
FT_Module module;
FT_Pixel_Mode pixel_mode;
@ -362,7 +376,19 @@
if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
{
if ( slot->format == FT_GLYPH_FORMAT_SVG )
{
SVG_Service svg_service;
module = FT_Get_Module(slot->library, "ot-svg" );
svg_service = (SVG_Service)module->clazz->module_interface;
return svg_service->preset_slot( module, slot, FALSE );
}
else
return 1;
return 1;
}
if ( origin )
{
@ -551,7 +577,23 @@
slot->subglyphs = NULL;
slot->control_data = NULL;
slot->control_len = 0;
#ifndef FT_CONFIG_OPTION_SVG
slot->other = NULL;
#else
if ( !( slot->face->face_flags & FT_FACE_FLAG_SVG ) )
slot->other = NULL;
else
{
if ( slot->internal->flags & FT_GLYPH_OWN_GZIP_SVG )
{
FT_Memory memory = slot->face->memory;
FT_SVG_Document doc = (FT_SVG_Document)slot->other;
FT_FREE( doc->svg_document );
slot->internal->load_flags &= ~FT_GLYPH_OWN_GZIP_SVG;
}
}
#endif
slot->format = FT_GLYPH_FORMAT_NONE;
slot->linearHoriAdvance = 0;
@ -569,6 +611,20 @@
FT_Memory memory = driver->root.memory;
#ifdef FT_CONFIG_OPTION_SVG
if ( slot->face->face_flags & FT_FACE_FLAG_SVG )
{
/* free memory in case svg was there */
if ( slot->internal->flags & FT_GLYPH_OWN_GZIP_SVG )
{
FT_SVG_Document doc = (FT_SVG_Document)slot->other;
FT_FREE( doc->svg_document );
slot->internal->flags &= ~FT_GLYPH_OWN_GZIP_SVG;
}
FT_FREE( slot->other );
}
#endif
if ( clazz->done_slot )
clazz->done_slot( slot );
@ -587,6 +643,7 @@
FT_FREE( slot->internal );
}
}
@ -4403,6 +4460,13 @@
render->render = clazz->render_glyph;
}
#ifdef FT_CONFIG_OPTION_SVG
if ( clazz->glyph_format == FT_GLYPH_FORMAT_SVG )
{
render->render = clazz->render_glyph;
}
#endif
/* add to list */
node->data = module;
FT_List_Add( &library->renderers, node );
@ -4538,7 +4602,6 @@
{
case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */
break;
default:
if ( slot->internal->load_flags & FT_LOAD_COLOR )
{
@ -5546,5 +5609,4 @@
return 0;
}
/* END */

View File

@ -177,7 +177,8 @@
if ( !error )
{
if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP ||
face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ||
face->glyph->format == FT_GLYPH_FORMAT_SVG )
{
/* ok, copy it */
FT_Glyph glyph;

View File

@ -347,6 +347,56 @@
if ( load_flags & FT_LOAD_SBITS_ONLY )
return FT_THROW( Invalid_Argument );
#ifdef FT_CONFIG_OPTION_SVG
/* check for OT-SVG */
if ( ( load_flags & FT_LOAD_COLOR ) &&
( ((TT_Face)glyph->root.face)->svg ) )
{
SFNT_Service sfnt;
FT_Short leftBearing;
FT_Short topBearing;
FT_UShort advanceX;
FT_UShort advanceY;
if ( ( size->root.metrics.x_ppem < 1 ||
size->root.metrics.y_ppem < 1 ) )
{
error = FT_THROW( Invalid_Size_Handle );
return error;
}
FT_TRACE3(( "Attemping to load SVG glyph\n" ));
sfnt = (SFNT_Service)((TT_Face)glyph->root.face)->sfnt;
error = sfnt->load_svg_doc( (FT_GlyphSlot)glyph, glyph_index );
if( error == FT_Err_Ok )
{
FT_TRACE3(( "Successfully loaded SVG glyph\n" ));
glyph->root.format = FT_GLYPH_FORMAT_SVG;
sfnt->get_metrics( face,
FALSE,
glyph_index,
&leftBearing,
&advanceX );
sfnt->get_metrics( face,
TRUE,
glyph_index,
&topBearing,
&advanceY );
advanceX *= ((float)glyph->root.face->size->metrics.x_ppem)/
((float)glyph->root.face->units_per_EM) * 64.0;
advanceY *= ((float)glyph->root.face->size->metrics.y_ppem)/
((float)glyph->root.face->units_per_EM) * 64.0;
glyph->root.metrics.horiAdvance = advanceX;
glyph->root.metrics.vertAdvance = advanceY;
return error;
}
FT_TRACE3(( "Failed to load SVG glyph\n" ));
}
#endif
/* if we have a CID subfont, use its matrix (which has already */
/* been multiplied with the root matrix) */

View File

@ -36,6 +36,7 @@ SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \
$(SFNT_DIR)/ttcmap.c \
$(SFNT_DIR)/ttcolr.c \
$(SFNT_DIR)/ttcpal.c \
$(SFNT_DIR)/ttsvg.c \
$(SFNT_DIR)/ttkern.c \
$(SFNT_DIR)/ttload.c \
$(SFNT_DIR)/ttmtx.c \

View File

@ -37,6 +37,10 @@
#include "ttcpal.h"
#endif
#ifdef FT_CONFIG_OPTION_SVG
#include "ttsvg.h" /* OpenType SVG support */
#endif
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
#include "ttpost.h"
#endif
@ -1208,6 +1212,12 @@
#define PUT_EMBEDDED_BITMAPS( a ) NULL
#endif
#ifdef FT_CONFIG_OPTION_SVG
#define PUT_SVG_SUPPORT( a ) a
#else
#define PUT_SVG_SUPPORT( a ) NULL
#endif
#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
#define PUT_COLOR_LAYERS( a ) a
#else
@ -1294,7 +1304,14 @@
tt_face_get_metrics, /* TT_Get_Metrics_Func get_metrics */
tt_face_get_name, /* TT_Get_Name_Func get_name */
sfnt_get_name_id /* TT_Get_Name_ID_Func get_name_id */
sfnt_get_name_id, /* TT_Get_Name_ID_Func get_name_id */
PUT_SVG_SUPPORT( tt_face_load_svg ),
/* TT_Load_Table_Func load_svg */
PUT_SVG_SUPPORT( tt_face_free_svg ),
/* TT_Free_Table_Func free_svg */
PUT_SVG_SUPPORT( tt_face_load_svg_doc )
/* TT_Load_Svg_Doc_Func load_svg_doc */
)

View File

@ -27,6 +27,7 @@
#include "ttcmap.c"
#include "ttcolr.c"
#include "ttcpal.c"
#include "ttsvg.c"
#include "ttkern.c"
#include "ttload.c"

View File

@ -953,6 +953,12 @@
LOAD_( colr );
}
#ifdef FT_CONFIG_OPTION_SVG
/* opentype svg glyph support */
if ( sfnt->load_svg )
LOAD_( svg );
#endif
/* consider the pclt, kerning, and gasp tables as optional */
LOAD_( pclt );
LOAD_( gasp );
@ -1372,6 +1378,11 @@
sfnt->free_cpal( face );
sfnt->free_colr( face );
}
#ifdef FT_CONFIG_OPTION_SVG
/* free svg data */
if ( sfnt->free_svg )
sfnt->free_svg( face );
#endif
}
#ifdef TT_CONFIG_OPTION_BDF

349
src/sfnt/ttsvg.c Normal file
View File

@ -0,0 +1,349 @@
/****************************************************************************
*
* ttsvg.c
*
* OpenType SVG Color (specification).
*
* Copyright (C) 2018-2019 by
* David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* `SVG' table specification:
*
* https://docs.microsoft.com/en-us/typography/opentype/spec/svg
*
*/
#include <ft2build.h>
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
#include FT_TRUETYPE_TAGS_H
#include FT_GZIP_H
#include FT_OTSVG_H
#ifdef FT_CONFIG_OPTION_SVG
#include "ttsvg.h"
typedef struct Svg_
{
FT_UShort version; /* Table version (starting at 0) */
FT_UShort num_entries; /* Number of SVG document records */
/* Pointer to the starting of SVG Document List */
FT_Byte* svg_doc_list;
/* Memory that backs up SVG */
void* table;
FT_ULong table_size;
} Svg;
#undef FT_COMPONENT
#define FT_COMPONENT ttsvg
FT_LOCAL_DEF( FT_Error )
tt_face_load_svg( TT_Face face,
FT_Stream stream )
{
FT_Error error;
FT_Memory memory = face->root.memory;
FT_ULong table_size;
FT_Byte* table = NULL;
FT_Byte* p = NULL;
Svg* svg = NULL;
FT_ULong offsetToSVGDocumentList;
error = face->goto_table( face, TTAG_SVG, stream, &table_size );
if( error )
goto NoSVG;
if( FT_FRAME_EXTRACT( table_size, table ))
goto NoSVG;
/* Allocate the memory for the Svg object */
if( FT_NEW( svg ) )
goto NoSVG;
p = table;
svg->version = FT_NEXT_USHORT( p );
offsetToSVGDocumentList = FT_NEXT_ULONG( p );
if( offsetToSVGDocumentList == 0 )
goto InvalidTable;
svg->svg_doc_list = (FT_Byte*)( table + offsetToSVGDocumentList );
p = svg->svg_doc_list;
svg->num_entries = FT_NEXT_USHORT( p );
FT_TRACE3(( "version: %d\n", svg->version ));
FT_TRACE3(( "num entiries: %d\n", svg->num_entries ));
svg->table = table;
svg->table_size = table_size;
face->svg = svg;
face->root.face_flags |= FT_FACE_FLAG_SVG;
return FT_Err_Ok;
InvalidTable:
error = FT_THROW( Invalid_Table );
NoSVG:
FT_FRAME_RELEASE( table );
FT_FREE( svg );
face->svg = NULL;
return error;
}
FT_LOCAL_DEF( void )
tt_face_free_svg( TT_Face face )
{
FT_Memory memory = face->root.memory;
FT_Stream stream = face->root.stream;
Svg* svg = (Svg*) face->svg;
if( svg )
{
FT_FRAME_RELEASE( svg->table );
FT_FREE( svg );
}
}
typedef struct Svg_doc_
{
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
FT_ULong offset;
FT_ULong length;
} Svg_doc;
static Svg_doc
extract_svg_doc( FT_Byte* stream )
{
Svg_doc doc;
doc.start_glyph_id = FT_NEXT_USHORT( stream );
doc.end_glyph_id = FT_NEXT_USHORT( stream );
doc.offset = FT_NEXT_ULONG( stream );
doc.length = FT_NEXT_ULONG( stream );
return doc;
}
static FT_Int
compare_svg_doc( Svg_doc doc,
FT_UInt glyph_index )
{
if ( glyph_index < doc.start_glyph_id )
return -1;
else if ( glyph_index > doc.end_glyph_id )
return 1;
else
return 0;
}
static FT_Error
find_doc( FT_Byte* stream,
FT_UShort num_entries,
FT_UInt glyph_index,
FT_ULong *doc_offset,
FT_ULong *doc_length,
FT_UShort *start_glyph,
FT_UShort *end_glyph )
{
FT_Error error;
Svg_doc start_doc;
Svg_doc mid_doc;
Svg_doc end_doc;
FT_Bool found = FALSE;
FT_UInt i = 0;
FT_UInt start_index = 0;
FT_UInt end_index = num_entries - 1;
FT_Int comp_res;
/* search algo */
if ( num_entries == 0 )
{
error = FT_THROW( Invalid_Table );
return error;
}
FT_TRACE6(( "--- binary search glyph id: %d ---\n", glyph_index ));
start_doc = extract_svg_doc( stream + start_index * 12 );
end_doc = extract_svg_doc( stream + end_index * 12 );
FT_TRACE6(( "--- start glyph ---\n" ));
FT_TRACE6(( "start_id: %d\n", start_doc.start_glyph_id ));
FT_TRACE6(( "end_id: %d\n", start_doc.end_glyph_id ));
FT_TRACE6(( "--- end glyph ---\n" ));
FT_TRACE6(( "start_id: %d\n", end_doc.start_glyph_id ));
FT_TRACE6(( "end_id: %d\n", end_doc.end_glyph_id ));
if ( ( compare_svg_doc( start_doc, glyph_index ) == -1 ) ||
( compare_svg_doc( end_doc, glyph_index ) == 1 ) )
{
error = FT_THROW( Invalid_Glyph_Index );
return error;
}
while ( start_index <= end_index )
{
i = ( start_index + end_index ) / 2;
mid_doc = extract_svg_doc( stream + i * 12 );
FT_TRACE6(( "--- current glyph ---\n" ));
FT_TRACE6(( "start_id: %d\n", mid_doc.start_glyph_id ));
FT_TRACE6(( "end_id: %d\n", mid_doc.end_glyph_id ));
comp_res = compare_svg_doc( mid_doc, glyph_index );
if ( comp_res == 1 )
{
start_index = i + 1;
start_doc = extract_svg_doc( stream + start_index * 4 );
FT_TRACE6(( "RIGHT\n" ));
}
else if ( comp_res == -1 )
{
end_index = i - 1;
end_doc = extract_svg_doc( stream + end_index * 4 );
FT_TRACE6(( "LEFT\n" ));
}
else
{
found = TRUE;
FT_TRACE5(( "FOUND\n" ));
break;
}
}
FT_TRACE5(( "--- binary search end ---\n" ));
/* search algo end */
if ( found != TRUE )
{
FT_TRACE5(( "NOT FOUND\n" ));
error = FT_THROW( Invalid_Glyph_Index );
}
else
{
*doc_offset = mid_doc.offset;
*doc_length = mid_doc.length;
*start_glyph = mid_doc.start_glyph_id;
*end_glyph = mid_doc.end_glyph_id;
error = FT_Err_Ok;
}
return error;
}
FT_LOCAL_DEF( FT_Error )
tt_face_load_svg_doc( FT_GlyphSlot glyph,
FT_UInt glyph_index )
{
FT_Byte* doc_list; /* Pointer to the Svg Document List */
FT_UShort num_entries; /* Total no of entires in doc list */
FT_ULong doc_offset;
FT_ULong doc_length;
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
FT_ULong uncomp_size;
FT_Byte* uncomp_buffer;
FT_Error error = FT_Err_Ok;
TT_Face face = (TT_Face)glyph->face;
FT_Memory memory = face->root.memory;
Svg* svg = face->svg;
FT_SVG_Document svg_document = glyph->other;
FT_ASSERT( !( svg == NULL ) );
doc_list = svg->svg_doc_list;
num_entries = FT_NEXT_USHORT( doc_list );
error = find_doc( doc_list, num_entries, glyph_index,
&doc_offset, &doc_length,
&start_glyph_id, &end_glyph_id );
if ( error != FT_Err_Ok )
goto Exit;
doc_list = svg->svg_doc_list; /* Reset to so we can use it again */
doc_list = (FT_Byte*)( doc_list + doc_offset );
if( ( doc_list[0] == 0x1F ) && ( doc_list[1] == 0x8B )
&& ( doc_list[2] == 0x08 ) )
{
/* get the size of the orignal document. This helps in alotting the
* buffer to accomodate the uncompressed version. The last 4 bytes
* of the compressed document are equal to orignal_size modulo 2^32.
* Since SVG docs will be lesser in size then 2^32, we can use this
* accurately. The four bytes are stored in little-endian format.
*/
FT_TRACE4(( "SVG document found is GZIP compressed\n" ));
uncomp_size = (FT_ULong)doc_list[doc_length - 1] << 24 |
(FT_ULong)doc_list[doc_length - 2] << 16 |
(FT_ULong)doc_list[doc_length - 3] << 8 |
(FT_ULong)doc_list[doc_length - 4];
uncomp_buffer = (FT_Byte*) memory->alloc( memory, uncomp_size );
error = FT_Gzip_Uncompress( memory, uncomp_buffer, &uncomp_size,
doc_list, doc_length );
if ( error != FT_Err_Ok )
{
memory->free( memory, uncomp_buffer );
error = FT_THROW( Invalid_Table );
goto Exit;
}
glyph->internal->flags |= FT_GLYPH_OWN_GZIP_SVG;
doc_list = uncomp_buffer;
doc_length = uncomp_size;
}
svg_document->svg_document = doc_list;
svg_document->svg_document_length = doc_length;
svg_document->metrics = glyph->face->size->metrics;
svg_document->units_per_EM = glyph->face->units_per_EM;
svg_document->start_glyph_id = start_glyph_id;
svg_document->end_glyph_id = end_glyph_id;
svg_document->transform.xx = 0x10000;
svg_document->transform.xy = 0;
svg_document->transform.yx = 0;
svg_document->transform.yy = 0x10000;
svg_document->delta.x = 0;
svg_document->delta.y = 0;
FT_TRACE5(( "start_glyph_id: %d\n", start_glyph_id ));
FT_TRACE5(( "end_glyph_id: %d\n", end_glyph_id ));
FT_TRACE5(( "svg_document:\n%.*s\n", doc_length, doc_list ));
glyph->other = svg_document;
Exit:
return error;
}
#else /* !FT_CONFIG_OPTION_SVG */
/* ANSI C doesn't like empty source files */
typedef int _tt_svg_dummy;
#endif /* !FT_CONFIG_OPTION_SVG */

40
src/sfnt/ttsvg.h Normal file
View File

@ -0,0 +1,40 @@
/****************************************************************************
*
* ttsvg.h
*
* OpenType SVG Color (specification).
*
* Copyright (C) 2018-2019 by
* David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef __TTSVG_H__
#define __TTSVG_H__
#include <ft2build.h>
#include FT_INTERNAL_TRUETYPE_TYPES_H
FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
tt_face_load_svg( TT_Face face,
FT_Stream stream );
FT_LOCAL( void )
tt_face_free_svg( TT_Face face );
FT_LOCAL( FT_Error )
tt_face_load_svg_doc( FT_GlyphSlot glyph,
FT_UInt glyph_index );
FT_END_HEADER
#endif /* __TTSVG_H__ */
/* END */

302
src/svg/ftsvg.c Normal file
View File

@ -0,0 +1,302 @@
/****************************************************************************
*
* ftsvg.c
*
* The FreeType svg renderer interface (body).
*
* Copyright (C) 1996-2019 by
* David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_SERVICE_H
#include FT_SERVICE_PROPERTIES_H
#include FT_OTSVG_H
#include FT_INTERNAL_SVG_INTERFACE_H
#include FT_BBOX_H
#include "ftsvg.h"
#include "svgtypes.h"
#ifdef FT_CONFIG_OPTION_DEFAULT_SVG
#include "rsvg_port.h"
#endif
#undef FT_COMPONENT
#define FT_COMPONENT otsvg
#ifdef FT_CONFIG_OPTION_SVG
/* ft_svg_init */
static FT_Error
ft_svg_init( SVG_Renderer svg_module )
{
FT_Error error = FT_Err_Ok;
svg_module->loaded = FALSE;
#ifdef FT_CONFIG_OPTION_DEFAULT_SVG
FT_TRACE3(( "ft_svg_init: Default hooks being set\n" ));
svg_module->hooks.init_svg = (SVG_Lib_Init_Func)rsvg_port_init;
svg_module->hooks.free_svg = (SVG_Lib_Free_Func)rsvg_port_free;
svg_module->hooks.render_svg = (SVG_Lib_Render_Func)rsvg_port_render;
svg_module->hooks.preset_slot = (SVG_Lib_Preset_Slot_Func)rsvg_port_preset_slot;
svg_module->hooks_set = TRUE;
#else
FT_TRACE3(( "ft_svg_init: No default hooks set\n" ));
svg_module->hooks_set = FALSE;
#endif
return error;
}
static void
ft_svg_done( SVG_Renderer svg_module )
{
FT_Library library = svg_module->root.root.library;
if ( svg_module->loaded == TRUE &&
svg_module->hooks_set == TRUE )
svg_module->hooks.free_svg( library );
svg_module->loaded = FALSE;
}
static FT_Error
ft_svg_preset_slot( FT_Module module,
FT_GlyphSlot slot,
FT_Bool cache )
{
SVG_Renderer svg_renderer = (SVG_Renderer)module;
SVG_RendererHooks hooks = svg_renderer->hooks;
if ( svg_renderer->hooks_set == FALSE )
{
FT_TRACE1(( "Hooks are NOT set. Can't render OT-SVG glyphs\n" ));
return FT_THROW( Missing_SVG_Hooks );
}
return hooks.preset_slot( slot, cache );
}
static FT_Error
ft_svg_render( FT_Renderer renderer,
FT_GlyphSlot slot,
FT_Render_Mode mode,
const FT_Vector* origin )
{
SVG_Renderer svg_renderer = (SVG_Renderer)renderer;
FT_Library library = renderer->root.library;
FT_Memory memory = library->memory;
FT_Error error;
FT_ULong size_image_buffer;
SVG_RendererHooks hooks = svg_renderer->hooks;
FT_UNUSED( mode );
FT_UNUSED( origin );
if ( svg_renderer->hooks_set == FALSE )
{
FT_TRACE1(( "Hooks are NOT set. Can't render OT-SVG glyphs\n" ));
return FT_THROW( Missing_SVG_Hooks );
}
if ( svg_renderer->loaded == FALSE )
{
FT_TRACE3(( "ft_svg_render: first rendering, calling init hook\n" ));
error = hooks.init_svg( library );
svg_renderer->loaded = TRUE;
}
ft_svg_preset_slot( (FT_Module)renderer, slot, TRUE);
size_image_buffer = slot->bitmap.pitch * slot->bitmap.rows;
FT_MEM_ALLOC( slot->bitmap.buffer, size_image_buffer);
if ( error )
return error;
error = hooks.render_svg( slot );
if ( error )
FT_FREE( slot->bitmap.buffer );
else
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
return error;
}
static const SVG_Interface svg_interface = {
(Preset_Bitmap_Func)ft_svg_preset_slot
};
static FT_Error
ft_svg_property_set( FT_Module module,
const char* property_name,
const void* value,
FT_Bool value_is_string )
{
FT_Error error = FT_Err_Ok;
SVG_Renderer renderer = (SVG_Renderer)module;
if ( !ft_strcmp( property_name, "svg_hooks" ) )
{
SVG_RendererHooks* hooks;
if ( value_is_string == TRUE )
return FT_THROW( Invalid_Argument );
hooks = (SVG_RendererHooks*)value;
renderer->hooks = *hooks;
renderer->hooks_set = TRUE;
}
else
error = FT_THROW( Missing_Property );
return error;
}
static FT_Error
ft_svg_property_get( FT_Module module,
const char* property_name,
const void* value )
{
FT_Error error = FT_Err_Ok;
SVG_Renderer renderer = (SVG_Renderer)module;
if ( !ft_strcmp( property_name, "svg_hooks" ) )
{
SVG_RendererHooks* hooks = (SVG_RendererHooks*)value;
*hooks = renderer->hooks;
}
else
error = FT_THROW( Missing_Property );
return error;
}
FT_DEFINE_SERVICE_PROPERTIESREC(
ft_svg_service_properties,
(FT_Properties_SetFunc)ft_svg_property_set, /* set_property */
(FT_Properties_GetFunc)ft_svg_property_get /* get_property */
)
FT_DEFINE_SERVICEDESCREC1(
ft_svg_services,
FT_SERVICE_ID_PROPERTIES, &ft_svg_service_properties )
FT_CALLBACK_DEF( FT_Module_Interface )
ft_svg_get_interface( FT_Module module,
const char* ft_svg_interface )
{
FT_Module_Interface result;
FT_UNUSED( module );
result = ft_service_list_lookup( ft_svg_services, ft_svg_interface );
if ( result )
return result;
return 0;
}
static FT_Error
ft_svg_transform( FT_Renderer renderer,
FT_GlyphSlot slot,
const FT_Matrix* _matrix,
const FT_Vector* _delta )
{
FT_SVG_Document doc = (FT_SVG_Document)slot->other;
FT_Matrix* matrix = (FT_Matrix*)_matrix;
FT_Vector* delta = (FT_Vector*)_delta;
FT_Matrix tmp_matrix;
FT_Vector tmp_delta;
FT_Matrix a, b;
FT_Pos x, y;
FT_UNUSED( renderer );
if ( !matrix )
{
tmp_matrix.xx = 0x10000;
tmp_matrix.xy = 0;
tmp_matrix.yx = 0;
tmp_matrix.yy = 0x10000;
matrix = &tmp_matrix;
}
if ( !delta )
{
tmp_delta.x = 0;
tmp_delta.y = 0;
delta = &tmp_delta;
}
a = doc->transform;
b = *matrix;
FT_Matrix_Multiply( &b, &a );
x = ADD_LONG(ADD_LONG(
FT_MulFix(matrix->xx, doc->delta.x),
FT_MulFix(matrix->xy, doc->delta.y)),
delta->x);
y = ADD_LONG(ADD_LONG(
FT_MulFix(matrix->yx, doc->delta.x),
FT_MulFix(matrix->yy, doc->delta.y)),
delta->y);
doc->delta.x = x;
doc->delta.y = y;
doc->transform = a;
return FT_Err_Ok;
}
#endif
#ifdef FT_CONFIG_OPTION_SVG
#define PUT_SVG_MODULE( a ) a
#define SVG_GLYPH_FORMAT FT_GLYPH_FORMAT_SVG
#else
#define PUT_SVG_MODULE( a ) NULL
#define SVG_GLYPH_FORMAT FT_GLYPH_FORMAT_NONE
#endif
FT_DEFINE_RENDERER(
ft_svg_renderer_class,
FT_MODULE_RENDERER,
sizeof( SVG_RendererRec ),
"ot-svg",
0x10000L,
0x20000L,
(const void*)PUT_SVG_MODULE( &svg_interface ), /* module specific interface */
(FT_Module_Constructor)PUT_SVG_MODULE( ft_svg_init ), /* module_init */
(FT_Module_Destructor)PUT_SVG_MODULE( ft_svg_done ), /* module_done */
PUT_SVG_MODULE( ft_svg_get_interface ), /* get_interface */
SVG_GLYPH_FORMAT,
(FT_Renderer_RenderFunc)PUT_SVG_MODULE( ft_svg_render ),
(FT_Renderer_TransformFunc)PUT_SVG_MODULE( ft_svg_transform ),
NULL,
NULL,
NULL
)

33
src/svg/ftsvg.h Normal file
View File

@ -0,0 +1,33 @@
/****************************************************************************
*
* ftsvg.h
*
* The FreeType svg renderer interface (specification).
*
* Copyright (C) 1996-2019 by
* David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTSVG_H_
#define FTSVG_H_
#include <ft2build.h>
#include FT_RENDER_H
#include FT_INTERNAL_OBJECTS_H
FT_BEGIN_HEADER
FT_DECLARE_RENDERER( ft_svg_renderer_class )
FT_END_HEADER
#endif /* FTSVG_H_ */
/* END */

23
src/svg/module.mk Normal file
View File

@ -0,0 +1,23 @@
#
# FreeType 2 svg renderer module definition
#
# Copyright (C) 1996-2019 by
# David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
FTMODULE_H_COMMANDS += SVG_MODULE
define SVG_MODULE
$(OPEN_DRIVER) FT_Renderer_Class, ft_svg_renderer_class $(CLOSE_DRIVER)
$(ECHO_DRIVER)ot-svg $(ECHO_DRIVER_DESC)ot-svg glyph renderer module$(ECHO_DRIVER_DONE)
endef
# EOF

71
src/svg/rules.mk Normal file
View File

@ -0,0 +1,71 @@
#
# FreeType 2 svg renderer module build rules
#
# Copyright (C) 1996-2019 by
# David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
# svg renderer driver directory
#
SVG_DIR := $(SRC_DIR)/svg
# compilation flags for the driver
#
SVG_COMPILE := $(CC) $(ANSIFLAGS) \
$I$(subst /,$(COMPILER_SEP),$(SVG_DIR)) \
$(INCLUDE_FLAGS) \
$(FT_CFLAGS)
# svg renderer sources (i.e., C files)
#
SVG_DRV_SRC := $(SVG_DIR)/ftsvg.c \
$(SVG_DIR)/rsvg_port.c
# svg renderer headers
#
SVG_DRV_H := $(SVG_DIR)/ftsvg.h \
$(SVG_DIR)/svgtypes.h \
$(SVG_DIR)/rsvg_port.h
# svg renderer object(s)
#
# SVG_DRV_OBJ_M is used during `multi' builds.
# SVG_DRV_OBJ_S is used during `single' builds.
#
SVG_DRV_OBJ_M := $(SVG_DRV_SRC:$(SVG_DIR)/%.c=$(OBJ_DIR)/%.$O)
SVG_DRV_OBJ_S := $(OBJ_DIR)/svg.$O
# svg renderer source file for single build
#
SVG_DRV_SRC_S := $(SVG_DIR)/svg.c
# svg renderer - single object
#
$(SVG_DRV_OBJ_S): $(SVG_DRV_SRC_S) $(SVG_DRV_SRC) \
$(FREETYPE_H) $(SVG_DRV_H)
$(SVG_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SVG_DRV_SRC_S))
# svg renderer - multiple objects
#
$(OBJ_DIR)/%.$O: $(SVG_DIR)/%.c $(FREETYPE_H) $(SVG_DRV_H)
$(SVG_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
# update main driver object lists
#
DRV_OBJS_S += $(SVG_DRV_OBJ_S)
DRV_OBJS_M += $(SVG_DRV_OBJ_M)
# EOF

31
src/svg/svg.c Normal file
View File

@ -0,0 +1,31 @@
/****************************************************************************
*
* svg.c
*
* FreeType svg renderer module component (body only).
*
* Copyright (C) 1996-2019 by
* David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include <ft2build.h>
#include FT_FREETYPE_H
#ifdef FT_CONFIG_OPTION_DEFAULT_SVG
#include "rsvg_port.c"
#endif
#include "svgtypes.h"
#include "ftsvg.c"
/* END */

37
src/svg/svgtypes.h Normal file
View File

@ -0,0 +1,37 @@
/****************************************************************************
*
* svgtypes.h
*
* The FreeType svg renderer internal types (specification).
*
* Copyright (C) 1996-2019 by
* David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTSVGTYPES_H
#define FTSVGTYPES_H
#include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
#include FT_RENDER_H
#include FT_OTSVG_H
typedef struct SVG_RendererRec_
{
FT_RendererRec root; /* This inherits FT_RendererRec */
FT_Bool loaded;
FT_Bool hooks_set;
SVG_RendererHooks hooks; /* Holds out hooks to the outside library */
} SVG_RendererRec;
typedef struct SVG_RendererRec_* SVG_Renderer;
#endif

View File

@ -2907,6 +2907,48 @@
goto Exit;
}
#ifdef FT_CONFIG_OPTION_SVG
/* check for OT-SVG */
if ( ( load_flags & FT_LOAD_COLOR ) && ( ((TT_Face)glyph->face)->svg ) )
{
SFNT_Service sfnt;
FT_Short leftBearing;
FT_Short topBearing;
FT_UShort advanceX;
FT_UShort advanceY;
FT_TRACE3(( "Attemping to load SVG glyph\n" ));
sfnt = (SFNT_Service)((TT_Face)glyph->face)->sfnt;
error = sfnt->load_svg_doc( glyph, glyph_index );
if( error == FT_Err_Ok )
{
FT_TRACE3(( "Successfully loaded SVG glyph\n" ));
glyph->format = FT_GLYPH_FORMAT_SVG;
sfnt->get_metrics( (TT_Face)glyph->face,
FALSE,
glyph_index,
&leftBearing,
&advanceX );
sfnt->get_metrics( (TT_Face)glyph->face,
TRUE,
glyph_index,
&topBearing,
&advanceY );
advanceX *= ((float)glyph->face->size->metrics.x_ppem)/
((float)glyph->face->units_per_EM) * 64.0;
advanceY *= ((float)glyph->face->size->metrics.y_ppem)/
((float)glyph->face->units_per_EM) * 64.0;
glyph->metrics.horiAdvance = advanceX;
glyph->metrics.vertAdvance = advanceY;
return error;
}
FT_TRACE3(( "Failed to load SVG glyph\n" ));
}
#endif
if ( load_flags & FT_LOAD_SBITS_ONLY )
{
error = FT_THROW( Invalid_Argument );