Added the incremental loading system for the CID 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
diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index 3c0a898..78088e0 100644
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -43,75 +43,112 @@
CID_Face face = (CID_Face)decoder->builder.face;
CID_FaceInfo cid = &face->cid;
FT_Byte* p;
- FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
FT_UInt fd_select;
- FT_ULong off1, glyph_len;
FT_Stream stream = face->root.stream;
FT_Error error = 0;
+ FT_Byte* charstring = 0;
+ FT_Memory memory = face->root.memory;
+ FT_UInt glyph_length = 0;
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ /* For incremental fonts get the character data using the callback function. */
+ if (face->root.incremental_interface)
+ {
+ FT_Data glyph_data;
+ error = face->root.incremental_interface->funcs->get_glyph_data(face->root.incremental_interface->object,
+ glyph_index,&glyph_data);
+ if (error)
+ goto Exit;
+ p = (FT_Byte*)glyph_data.pointer;
+ fd_select = (FT_UInt)cid_get_offset(&p,(FT_Byte)cid->fd_bytes);
+ glyph_data.pointer += cid->fd_bytes;
+ glyph_data.length -= cid->fd_bytes;
+ glyph_length = glyph_data.length;
+
+ if (glyph_length == 0)
+ goto Exit;
+ if (FT_ALLOC(charstring,glyph_length))
+ goto Exit;
+ ft_memcpy(charstring,glyph_data.pointer,glyph_length);
+ }
+else
+#endif
- /* read the CID font dict index and charstring offset from the CIDMap */
- if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
- glyph_index * entry_len ) ||
- FT_FRAME_ENTER( 2 * entry_len ) )
- goto Exit;
+ /* For ordinary fonts read the CID font dictionary index and charstring offset from the CIDMap. */
+ {
+ FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
+ FT_ULong off1;
+ if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
+ glyph_index * entry_len ) ||
+ FT_FRAME_ENTER( 2 * entry_len ) )
+ goto Exit;
- p = (FT_Byte*)stream->cursor;
- fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
- off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
- p += cid->fd_bytes;
- glyph_len = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
+ p = (FT_Byte*)stream->cursor;
+ fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
+ off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
+ p += cid->fd_bytes;
+ glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
+ FT_FRAME_EXIT();
- FT_FRAME_EXIT();
+ if (glyph_length == 0)
+ goto Exit;
+ if (FT_ALLOC(charstring,glyph_length))
+ goto Exit;
+ if (FT_STREAM_READ_AT(cid->data_offset + off1,charstring,glyph_length))
+ goto Exit;
+ }
- /* now, if the glyph is not empty, set up the subrs array, and parse */
- /* the charstrings */
- if ( glyph_len > 0 )
+ /* Now set up the subrs array and parse the charstrings. */
{
CID_FaceDict dict;
CID_Subrs cid_subrs = face->subrs + fd_select;
- FT_Byte* charstring;
- FT_Memory memory = face->root.memory;
-
+ FT_Int cs_offset;
- /* setup subrs */
+ /* Set up subrs */
decoder->num_subrs = cid_subrs->num_subrs;
decoder->subrs = cid_subrs->code;
decoder->subrs_len = 0;
- /* setup font matrix */
+ /* Set up font matrix */
dict = cid->font_dicts + fd_select;
decoder->font_matrix = dict->font_matrix;
decoder->font_offset = dict->font_offset;
decoder->lenIV = dict->private_dict.lenIV;
- /* the charstrings are encoded (stupid!) */
- /* load the charstrings, then execute it */
-
- if ( FT_ALLOC( charstring, glyph_len ) )
- goto Exit;
+ /* Decode the charstring. */
- if ( !FT_STREAM_READ_AT( cid->data_offset + off1,
- charstring, glyph_len ) )
- {
- FT_Int cs_offset;
+ /* Adjustment for seed bytes. */
+ cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
+ /* Decrypt only if lenIV >= 0. */
+ if ( decoder->lenIV >= 0 )
+ cid_decrypt( charstring, glyph_length, 4330 );
- /* Adjustment for seed bytes. */
- cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
+ error = decoder->funcs.parse_charstrings( decoder,
+ charstring + cs_offset,
+ glyph_length - cs_offset );
+ }
- /* Decrypt only if lenIV >= 0. */
- if ( decoder->lenIV >= 0 )
- cid_decrypt( charstring, glyph_len, 4330 );
+ FT_FREE( charstring );
- error = decoder->funcs.parse_charstrings( decoder,
- charstring + cs_offset,
- glyph_len - cs_offset );
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ /* Incremental fonts can optionally override the metrics. */
+ if (!error && face->root.incremental_interface && face->root.incremental_interface->funcs->get_glyph_metrics)
+ {
+ FT_Bool found = FALSE;
+ FT_Basic_Glyph_Metrics metrics;
+ error = face->root.incremental_interface->funcs->get_glyph_metrics(face->root.incremental_interface->object,
+ glyph_index,FALSE,&metrics,&found);
+ if (found)
+ {
+ decoder->builder.left_bearing.x = metrics.bearing_x;
+ decoder->builder.left_bearing.y = metrics.bearing_y;
+ decoder->builder.advance.x = metrics.advance;
+ decoder->builder.advance.y = 0;
}
-
- FT_FREE( charstring );
}
+#endif
Exit:
return error;