From 5f2dcadbf20742c6ea7cdcab08c6523c68bd5a85 Mon Sep 17 00:00:00 2001 From: Moazin Khatti Date: Mon, 24 Jun 2019 00:33:45 +0500 Subject: [PATCH] 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'. --- include/freetype/ftglyph.h | 15 +++++++++++++++ include/freetype/svgrenderer.h | 15 +++++++++++++++ src/base/ftglyph.c | 3 +++ src/sfnt/ttsvg.c | 1 + 4 files changed, 34 insertions(+) diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h index eea0f8c9f..6f8fdb87c 100644 --- a/include/freetype/ftglyph.h +++ b/include/freetype/ftglyph.h @@ -259,6 +259,20 @@ FT_BEGIN_HEADER * * metrics :: * A metrics object storing the size information. + * + * units_per_EM :: + * The size of the EM square. + * + * @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. */ typedef struct FT_SvgGlyphRec_ { @@ -267,6 +281,7 @@ FT_BEGIN_HEADER FT_ULong svg_document_length; FT_UInt glyph_index; FT_Size_Metrics metrics; + FT_UShort units_per_EM; /* TODO: (OT-SVG) Maybe put a transformation matrix here */ } FT_SvgGlyphRec; diff --git a/include/freetype/svgrenderer.h b/include/freetype/svgrenderer.h index 27e615507..449a443a8 100644 --- a/include/freetype/svgrenderer.h +++ b/include/freetype/svgrenderer.h @@ -165,6 +165,20 @@ FT_BEGIN_HEADER * * metrics :: * A metrics object storing the size information. + * + * units_per_EM :: + * The size of the EM square. + * + * @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. */ typedef struct FT_SVG_DocumentRec_ @@ -172,6 +186,7 @@ FT_BEGIN_HEADER FT_Byte* svg_document; FT_ULong svg_document_length; FT_Size_Metrics metrics; + FT_UShort units_per_EM; } FT_SVG_DocumentRec; /************************************************************************** diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c index 095469500..22cf25b75 100644 --- a/src/base/ftglyph.c +++ b/src/base/ftglyph.c @@ -327,6 +327,7 @@ glyph->svg_document_length = doc_length; glyph->glyph_index = slot->glyph_index; glyph->metrics = document->metrics; + glyph->units_per_EM = document->units_per_EM; /* copy the document into glyph */ FT_MEM_COPY( glyph->svg_document, document->svg_document, doc_length ); @@ -376,6 +377,7 @@ 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; /* allocate space for the svg document */ target->svg_document = memory->alloc( memory, @@ -410,6 +412,7 @@ 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; slot->format = FT_GLYPH_FORMAT_SVG; slot->other = document; diff --git a/src/sfnt/ttsvg.c b/src/sfnt/ttsvg.c index d9ad75a1d..798c9071a 100644 --- a/src/sfnt/ttsvg.c +++ b/src/sfnt/ttsvg.c @@ -232,6 +232,7 @@ 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; glyph->other = svg_document; glyph->metrics.horiAdvance *= ((float)glyph->face->size->metrics.x_ppem)/((float)glyph->face->units_per_EM) * 64.0;