summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoazin Khatti <moazinkhatri@gmail.com>2019-06-09 17:52:46 +0500
committerMoazin Khatti <moazinkhatri@gmail.com>2019-07-11 14:09:42 +0500
commit68d1cab0e16a1925584f5de7c5e0cd78fa811584 (patch)
treea4a6609677beffcb51bbf8854202e803619be159
parent7b9673dd016c1636771886063466910d0758e648 (diff)
downloadfreetype2-68d1cab0e16a1925584f5de7c5e0cd78fa811584.tar.gz
Very crude way to handle SVG data with only TTF outlined OT fonts. Gonna revert soon.
-rw-r--r--include/freetype/internal/sfnt.h13
-rw-r--r--include/freetype/internal/tttypes.h30
-rw-r--r--src/sfnt/sfdriver.c5
-rw-r--r--src/sfnt/ttsvg.c111
-rw-r--r--src/sfnt/ttsvg.h4
-rw-r--r--src/truetype/ttgload.c76
-rw-r--r--src/truetype/ttobjs.h15
7 files changed, 202 insertions, 52 deletions
diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index 94f512270..996cae895 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -312,6 +312,12 @@ FT_BEGIN_HEADER
TT_SBit_MetricsRec *ametrics );
+ /* OT-SVG to be documented later */
+ typedef FT_Error
+ (*TT_Load_Svg_Doc_Func)( FT_GlyphSlot glyph,
+ FT_UInt glyph_index );
+
+
/**************************************************************************
*
* @functype:
@@ -781,6 +787,7 @@ FT_BEGIN_HEADER
/* 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;
@@ -829,7 +836,8 @@ FT_BEGIN_HEADER
get_name_, \
get_name_id_, \
load_svg_, \
- free_svg_ ) \
+ free_svg_, \
+ load_svg_doc_ ) \
static const SFNT_Interface class_ = \
{ \
goto_table_, \
@@ -871,7 +879,8 @@ FT_BEGIN_HEADER
get_name_, \
get_name_id_, \
load_svg_, \
- free_svg_ \
+ free_svg_, \
+ load_svg_doc_ \
};
diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 42a921fe7..9ec8a1c96 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -967,8 +967,8 @@ FT_BEGIN_HEADER
* This structure/class is defined here because it is common to the
* following formats: TTF, OpenType-TT, and OpenType-CFF.
*
- * Note, however, that the classes TT_Size and TT_GlyphSlot are not shared
- * between font drivers, and are thus defined in `ttobjs.h`.
+ * Note, however, that the classes TT_Size and `TT_GlyphSlot'(not anymore),
+ * are not shared between font drivers, and are thus defined in `ttobjs.h`.
*
*/
@@ -988,6 +988,32 @@ FT_BEGIN_HEADER
*/
typedef struct TT_FaceRec_* TT_Face;
+ /**************************************************************************
+ *
+ * @Type:
+ * TT_GlyphSlotRec_
+ *
+ * @Description:
+ * A glyph slot that inherits from FT_GlyphSlotRec_ but adds more fields
+ *
+ */
+ typedef struct TT_GlyphSlotRec_
+ {
+ FT_GlyphSlotRec root;
+ FT_Byte* svg_document;
+ FT_ULong svg_document_length;
+ } TT_GlyphSlotRec;
+
+ /**************************************************************************
+ *
+ * @Type:
+ * TT_GlyphSlot
+ *
+ * @Description:
+ * A handle to a TrueType glyph slot object.
+ */
+ typedef struct TT_GlyphSlotRec_* TT_GlyphSlot;
+
/* a function type used for the truetype bytecode interpreter hooks */
typedef FT_Error
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index 11148b2cf..cff8ad69d 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -1297,8 +1297,9 @@
tt_face_get_name, /* TT_Get_Name_Func get_name */
sfnt_get_name_id, /* TT_Get_Name_ID_Func get_name_id */
- tt_face_load_svg, /* TT_Load_Table_Func load_svg */
- tt_face_free_svg /* TT_Free_Table_Func free_svg */
+ tt_face_load_svg, /* TT_Load_Table_Func load_svg */
+ tt_face_free_svg, /* TT_Free_Table_Func free_svg */
+ tt_face_load_svg_doc
)
diff --git a/src/sfnt/ttsvg.c b/src/sfnt/ttsvg.c
index 0ebe162e7..27e82968d 100644
--- a/src/sfnt/ttsvg.c
+++ b/src/sfnt/ttsvg.c
@@ -1,6 +1,6 @@
/****************************************************************************
*
- * ttsvg.h
+ * ttsvg.c
*
* OpenType SVG Color (specification).
*
@@ -27,6 +27,7 @@
#include <ft2build.h>
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
+#include FT_GZIP_H
#include "ttsvg.h"
@@ -113,3 +114,111 @@
FT_FREE( svg );
}
}
+
+ FT_Error
+ find_doc( FT_Byte* stream,
+ FT_UShort num_entries,
+ FT_UInt glyph_index,
+ FT_ULong *doc_offset,
+ FT_ULong *doc_length )
+ {
+ FT_Error error;
+ FT_UShort start_glyph_id;
+ FT_UShort end_glyph_id;
+ FT_ULong cur_doc_offset;
+ FT_ULong cur_doc_length;
+
+ FT_Bool found = FALSE;
+ FT_UInt i = 0;
+
+ /* For now it's linear search, later convert to binary search */
+ for ( i = 0; i < num_entries; i++)
+ {
+ start_glyph_id = FT_NEXT_USHORT( stream );
+ end_glyph_id = FT_NEXT_USHORT( stream );
+ cur_doc_offset = FT_NEXT_ULONG( stream );
+ cur_doc_length = FT_NEXT_ULONG( stream );
+
+ if ( ( glyph_index >= start_glyph_id) &&
+ ( glyph_index <= end_glyph_id ) )
+ {
+ found = TRUE;
+ *doc_offset = cur_doc_offset;
+ *doc_length = cur_doc_length;
+ break;
+ }
+ }
+ if ( found != TRUE )
+ error = FT_THROW( Invalid_Glyph_Index );
+ else
+ error = FT_Err_Ok;
+ return error;
+ }
+
+ FT_LOCAL_DEF(FT_Error)
+ tt_face_load_svg_doc( FT_GlyphSlot glyph_,
+ FT_UInt glyph_index )
+ {
+
+ TT_GlyphSlot glyph = (TT_GlyphSlot) glyph_;
+
+ /* TODO: properly clean stuff here on errors */
+
+ 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_ULong uncomp_size;
+ FT_Byte* uncomp_buffer;
+
+ FT_Bool is_gzip_encoded = FALSE;
+
+ FT_Error error = FT_Err_Ok;
+ TT_Face face = (TT_Face)glyph->root.face;
+ FT_Memory memory = face->root.memory;
+ Svg* svg = face->svg;
+
+ /* handle svg being 0x0 situation here */
+ 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 );
+ if ( error != FT_Err_Ok )
+ return error;
+
+ 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 ) )
+ {
+ is_gzip_encoded = TRUE;
+ 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];
+
+ /* TODO: memory allocated here needs to be freed somewhere */
+ 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 )
+ {
+ error = FT_THROW( Invalid_Table );
+ return error;
+ }
+
+ glyph->svg_document = uncomp_buffer;
+ glyph->svg_document_length = uncomp_size;
+ return FT_Err_Ok;
+ }
+
+ glyph->svg_document = doc_list;
+ glyph->svg_document_length = doc_length;
+ return FT_Err_Ok;
+ }
+
+
diff --git a/src/sfnt/ttsvg.h b/src/sfnt/ttsvg.h
index 1c6413be5..186d4c8e0 100644
--- a/src/sfnt/ttsvg.h
+++ b/src/sfnt/ttsvg.h
@@ -29,6 +29,10 @@ FT_BEGIN_HEADER
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__ */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index a04684086..6b2bb697a 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2204,7 +2204,8 @@
FT_BBox bbox;
FT_Fixed y_scale;
- TT_GlyphSlot glyph = loader->glyph;
+ TT_GlyphSlot glyph_ = (TT_GlyphSlot)loader->glyph;
+ FT_GlyphSlot glyph = (FT_GlyphSlot)glyph_;
TT_Size size = loader->size;
@@ -2392,7 +2393,7 @@
TT_SBit_MetricsRec sbit_metrics;
- face = (TT_Face)glyph->face;
+ face = (TT_Face)(glyph->root.face);
sfnt = (SFNT_Service)face->sfnt;
stream = face->root.stream;
@@ -2401,35 +2402,35 @@
glyph_index,
(FT_UInt)load_flags,
stream,
- &glyph->bitmap,
+ &(glyph->root.bitmap),
&sbit_metrics );
if ( !error )
{
- glyph->outline.n_points = 0;
- glyph->outline.n_contours = 0;
+ (glyph->root).outline.n_points = 0;
+ (glyph->root).outline.n_contours = 0;
- glyph->metrics.width = (FT_Pos)sbit_metrics.width * 64;
- glyph->metrics.height = (FT_Pos)sbit_metrics.height * 64;
+ (glyph->root).metrics.width = (FT_Pos)sbit_metrics.width * 64;
+ (glyph->root).metrics.height = (FT_Pos)sbit_metrics.height * 64;
- glyph->metrics.horiBearingX = (FT_Pos)sbit_metrics.horiBearingX * 64;
- glyph->metrics.horiBearingY = (FT_Pos)sbit_metrics.horiBearingY * 64;
- glyph->metrics.horiAdvance = (FT_Pos)sbit_metrics.horiAdvance * 64;
+ (glyph->root).metrics.horiBearingX = (FT_Pos)sbit_metrics.horiBearingX * 64;
+ (glyph->root).metrics.horiBearingY = (FT_Pos)sbit_metrics.horiBearingY * 64;
+ (glyph->root).metrics.horiAdvance = (FT_Pos)sbit_metrics.horiAdvance * 64;
- glyph->metrics.vertBearingX = (FT_Pos)sbit_metrics.vertBearingX * 64;
- glyph->metrics.vertBearingY = (FT_Pos)sbit_metrics.vertBearingY * 64;
- glyph->metrics.vertAdvance = (FT_Pos)sbit_metrics.vertAdvance * 64;
+ (glyph->root).metrics.vertBearingX = (FT_Pos)sbit_metrics.vertBearingX * 64;
+ (glyph->root).metrics.vertBearingY = (FT_Pos)sbit_metrics.vertBearingY * 64;
+ (glyph->root).metrics.vertAdvance = (FT_Pos)sbit_metrics.vertAdvance * 64;
- glyph->format = FT_GLYPH_FORMAT_BITMAP;
+ (glyph->root).format = FT_GLYPH_FORMAT_BITMAP;
if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
{
- glyph->bitmap_left = sbit_metrics.vertBearingX;
- glyph->bitmap_top = sbit_metrics.vertBearingY;
+ (glyph->root).bitmap_left = sbit_metrics.vertBearingX;
+ (glyph->root).bitmap_top = sbit_metrics.vertBearingY;
}
else
{
- glyph->bitmap_left = sbit_metrics.horiBearingX;
- glyph->bitmap_top = sbit_metrics.horiBearingY;
+ (glyph->root).bitmap_left = sbit_metrics.horiBearingX;
+ (glyph->root).bitmap_top = sbit_metrics.horiBearingY;
}
}
@@ -2438,6 +2439,22 @@
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
+ static FT_Error
+ load_svg_glyph( TT_GlyphSlot glyph,
+ FT_ULong glyph_index )
+ {
+ FT_Error error;
+ TT_Face face;
+ SFNT_Service sfnt;
+ FT_Byte* doc_list;
+
+ face = (TT_Face)(glyph->root).face;
+ sfnt = (SFNT_Service)face->sfnt;
+
+ error = sfnt->load_svg_doc( (FT_GlyphSlot)glyph, glyph_index );
+ return error;
+ }
+
static FT_Error
tt_loader_init( TT_Loader loader,
@@ -2454,12 +2471,12 @@
FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
- TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face );
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)(glyph->root).face );
#endif
#endif
- face = (TT_Face)glyph->face;
+ face = (TT_Face)(glyph->root.face);
stream = face->root.stream;
FT_ZERO( loader );
@@ -2711,7 +2728,7 @@
/* get face's glyph loader */
if ( !glyf_table_only )
{
- FT_GlyphLoader gloader = glyph->internal->loader;
+ FT_GlyphLoader gloader = (glyph->root).internal->loader;
FT_GlyphLoader_Rewind( gloader );
@@ -2775,13 +2792,13 @@
*/
FT_LOCAL_DEF( FT_Error )
TT_Load_Glyph( TT_Size size,
- TT_GlyphSlot glyph,
+ TT_GlyphSlot glyph_,
FT_UInt glyph_index,
FT_Int32 load_flags )
{
FT_Error error;
TT_LoaderRec loader;
-
+ FT_GlyphSlot glyph = (FT_GlyphSlot)glyph_;
FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
@@ -2796,7 +2813,7 @@
FT_Fixed y_scale = size->root.metrics.y_scale;
- error = load_sbit_image( size, glyph, glyph_index, load_flags );
+ error = load_sbit_image( size, glyph_, glyph_index, load_flags );
if ( FT_ERR_EQ( error, Missing_Bitmap ) )
{
/* the bitmap strike is incomplete and misses the requested glyph; */
@@ -2863,7 +2880,7 @@
if ( FT_IS_SCALABLE( glyph->face ) )
{
/* for the bbox we need the header only */
- (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
+ (void)tt_loader_init( &loader, size, glyph_, load_flags, TRUE );
(void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
tt_loader_done( &loader );
glyph->linearHoriAdvance = loader.linear;
@@ -2885,11 +2902,10 @@
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
- /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
- if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
+ /* OT-SVG part here */
+ if ( ( load_flags & FT_LOAD_COLOR ) && ( ((TT_Face)glyph->face)->svg ) )
{
- error = FT_THROW( Invalid_Size_Handle );
- goto Exit;
+ error = load_svg_glyph( glyph_, glyph_index );
}
if ( load_flags & FT_LOAD_SBITS_ONLY )
@@ -2898,7 +2914,7 @@
goto Exit;
}
- error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
+ error = tt_loader_init( &loader, size, glyph_, load_flags, FALSE );
if ( error )
goto Exit;
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index 9fc654d5d..d131a9a86 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -41,21 +41,6 @@ FT_BEGIN_HEADER
/**************************************************************************
*
- * @Type:
- * TT_GlyphSlot
- *
- * @Description:
- * A handle to a TrueType glyph slot object.
- *
- * @Note:
- * This is a direct typedef of FT_GlyphSlot, as there is nothing
- * specific about the TrueType glyph slot.
- */
- typedef FT_GlyphSlot TT_GlyphSlot;
-
-
- /**************************************************************************
- *
* @Struct:
* TT_GraphicsState
*