Added the incremental loading system for the TrueType driver. Tested using my own unit test code.
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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index c1385fd..25b9212 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -750,15 +750,18 @@
TT_Face face = (TT_Face)loader->face;
FT_ULong offset;
FT_Int contours_count;
- FT_UInt idx, num_points, count;
+ FT_UInt num_points, count;
FT_Fixed x_scale, y_scale;
FT_GlyphLoader gloader = loader->gloader;
FT_Bool opened_frame = 0;
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ struct FT_StreamRec_ inc_stream;
+#endif
/* check glyph index */
- idx = glyph_index;
- if ( idx >= (FT_UInt)face->root.num_glyphs )
+ glyph_index;
+ if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
{
error = TT_Err_Invalid_Glyph_Index;
goto Exit;
@@ -777,16 +780,40 @@
/* get horizontal metrics */
{
- FT_Short left_bearing;
- FT_UShort advance_width;
+ FT_Short left_bearing = 0;
+ FT_UShort advance_width = 0;
+
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ FT_Bool metrics_found = FALSE;
+
+ /* If this is an incrementally loaded font see if there are overriding metrics for this glyph. */
+ if (face->root.incremental_interface && face->root.incremental_interface->funcs->get_glyph_metrics)
+ {
+ FT_Basic_Glyph_Metrics m;
+ error = face->root.incremental_interface->funcs->get_glyph_metrics(face->root.incremental_interface->object,
+ glyph_index,FALSE,&m,&metrics_found);
+ if (error)
+ goto Exit;
+ left_bearing = (FT_Short)m.bearing_x;
+ advance_width = (FT_UShort)m.advance;
+ }
+ if (!metrics_found)
+ Get_HMetrics( face, glyph_index,
+ (FT_Bool)!( loader->load_flags &
+ FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
+ &left_bearing,
+ &advance_width );
- Get_HMetrics( face, idx,
+#else
+ Get_HMetrics( face, glyph_index,
(FT_Bool)!( loader->load_flags &
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
&left_bearing,
&advance_width );
+#endif
+
loader->left_bearing = left_bearing;
loader->advance = advance_width;
@@ -797,11 +824,37 @@
}
}
- offset = face->glyph_locations[idx];
- count = 0;
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ /*
+ Set 'offset' to the start of the glyph program relative to the start of the 'glyf' table,
+ and 'count' to the length of the glyph program in bytes.
- if ( idx < (FT_UInt)face->num_locations - 1 )
- count = face->glyph_locations[idx + 1] - offset;
+ If we are loading glyph data via the incremental interface, set the loader stream to a memory
+ stream reading the data returned by the interface.
+ */
+ if (face->root.incremental_interface)
+ {
+ FT_Data data;
+ error = face->root.incremental_interface->funcs->get_glyph_data(face->root.incremental_interface->object,
+ glyph_index,&data);
+ if (error)
+ goto Exit;
+ offset = 0;
+ count = data.length;
+ memset(&inc_stream,0,sizeof(inc_stream));
+ FT_Stream_OpenMemory(&inc_stream,data.pointer,data.length);
+ loader->stream = &inc_stream;
+ }
+ else
+#endif
+
+ {
+ offset = face->glyph_locations[glyph_index];
+ count = 0;
+
+ if ( glyph_index < (FT_UInt)face->num_locations - 1 )
+ count = face->glyph_locations[glyph_index + 1] - offset;
+ }
if ( count == 0 )
{
@@ -1200,7 +1253,7 @@
}
- static void
+ static FT_Error
compute_glyph_metrics( TT_Loader loader,
FT_UInt glyph_index )
{
@@ -1279,10 +1332,25 @@
FT_Pos left; /* scaled vertical left side bearing */
FT_Pos top; /* scaled vertical top side bearing */
FT_Pos advance; /* scaled vertical advance height */
+ FT_Bool metrics_found = FALSE;
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ /* If this is an incrementally loaded font see if there are overriding metrics for this glyph. */
+ if (face->root.incremental_interface && face->root.incremental_interface->funcs->get_glyph_metrics)
+ {
+ FT_Basic_Glyph_Metrics m;
+ FT_Error error =
+ face->root.incremental_interface->funcs->get_glyph_metrics(face->root.incremental_interface->object,
+ glyph_index,TRUE,&m,&metrics_found);
+ if (error)
+ return error;
+ top_bearing = (FT_Short)m.bearing_y;
+ advance_height = (FT_UShort)m.advance;
+ }
+#endif
- /* Get the unscaled `tsb' and `ah' */
- if ( face->vertical_info &&
+ /* Get the unscaled top bearing and advance height. */
+ if ( !metrics_found && face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 )
{
/* Don't assume that both the vertical header and vertical */
@@ -1377,6 +1445,8 @@
/* set glyph dimensions */
glyph->metrics.width = bbox.xMax - bbox.xMin;
glyph->metrics.height = bbox.yMax - bbox.yMin;
+
+ return 0;
}
@@ -1498,13 +1568,18 @@
/* seek to the beginning of the glyph table. For Type 42 fonts */
/* the table might be accessed from a Postscript stream or something */
/* else... */
-
- error = face->goto_table( face, TTAG_glyf, stream, 0 );
- if ( error )
- {
- FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" ));
- goto Exit;
- }
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ /* Don't look for the glyph table if this is an incremental font. */
+ if (!face->root.incremental_interface)
+#endif
+ {
+ error = face->goto_table( face, TTAG_glyf, stream, 0 );
+ if ( error )
+ {
+ FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" ));
+ goto Exit;
+ }
+ }
FT_MEM_SET( &loader, 0, sizeof ( loader ) );
@@ -1552,7 +1627,12 @@
loader.glyph = (FT_GlyphSlot)glyph;
loader.stream = stream;
- loader.glyf_offset = FT_STREAM_POS();
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ if (face->root.incremental_interface)
+ loader.glyf_offset = 0;
+ else
+#endif
+ loader.glyf_offset = FT_STREAM_POS();
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index cab9d1b..18616a0 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -197,9 +197,15 @@
goto Exit;
if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE )
- error = TT_Load_Locations( face, stream ) ||
- TT_Load_CVT ( face, stream ) ||
- TT_Load_Programs ( face, stream );
+ {
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ if ( !face->root.incremental_interface )
+ error = TT_Load_Locations( face, stream );
+ if ( !error )
+#endif
+ error = TT_Load_CVT ( face, stream ) ||
+ TT_Load_Programs ( face, stream );
+ }
/* initialize standard glyph loading routines */
TT_Init_Glyph_Loading( face );