00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_GLYPH_LOADER_H
00021 #include FT_INTERNAL_MEMORY_H
00022 #include FT_INTERNAL_OBJECTS_H
00023
00024 #undef FT_COMPONENT
00025 #define FT_COMPONENT trace_gloader
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 FT_BASE_DEF( FT_Error )
00069 FT_GlyphLoader_New( FT_Memory memory,
00070 FT_GlyphLoader *aloader )
00071 {
00072 FT_GlyphLoader loader;
00073 FT_Error error;
00074
00075
00076 if ( !FT_NEW( loader ) )
00077 {
00078 loader->memory = memory;
00079 *aloader = loader;
00080 }
00081 return error;
00082 }
00083
00084
00085
00086 FT_BASE_DEF( void )
00087 FT_GlyphLoader_Rewind( FT_GlyphLoader loader )
00088 {
00089 FT_GlyphLoad base = &loader->base;
00090 FT_GlyphLoad current = &loader->current;
00091
00092
00093 base->outline.n_points = 0;
00094 base->outline.n_contours = 0;
00095 base->num_subglyphs = 0;
00096
00097 *current = *base;
00098 }
00099
00100
00101
00102
00103 FT_BASE_DEF( void )
00104 FT_GlyphLoader_Reset( FT_GlyphLoader loader )
00105 {
00106 FT_Memory memory = loader->memory;
00107
00108
00109 FT_FREE( loader->base.outline.points );
00110 FT_FREE( loader->base.outline.tags );
00111 FT_FREE( loader->base.outline.contours );
00112 FT_FREE( loader->base.extra_points );
00113 FT_FREE( loader->base.subglyphs );
00114
00115 loader->base.extra_points2 = NULL;
00116
00117 loader->max_points = 0;
00118 loader->max_contours = 0;
00119 loader->max_subglyphs = 0;
00120
00121 FT_GlyphLoader_Rewind( loader );
00122 }
00123
00124
00125
00126 FT_BASE_DEF( void )
00127 FT_GlyphLoader_Done( FT_GlyphLoader loader )
00128 {
00129 if ( loader )
00130 {
00131 FT_Memory memory = loader->memory;
00132
00133
00134 FT_GlyphLoader_Reset( loader );
00135 FT_FREE( loader );
00136 }
00137 }
00138
00139
00140
00141 static void
00142 FT_GlyphLoader_Adjust_Points( FT_GlyphLoader loader )
00143 {
00144 FT_Outline* base = &loader->base.outline;
00145 FT_Outline* current = &loader->current.outline;
00146
00147
00148 current->points = base->points + base->n_points;
00149 current->tags = base->tags + base->n_points;
00150 current->contours = base->contours + base->n_contours;
00151
00152
00153 if ( loader->use_extra )
00154 {
00155 loader->current.extra_points = loader->base.extra_points +
00156 base->n_points;
00157
00158 loader->current.extra_points2 = loader->base.extra_points2 +
00159 base->n_points;
00160 }
00161 }
00162
00163
00164 FT_BASE_DEF( FT_Error )
00165 FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader )
00166 {
00167 FT_Error error;
00168 FT_Memory memory = loader->memory;
00169
00170
00171 if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
00172 {
00173 loader->use_extra = 1;
00174 loader->base.extra_points2 = loader->base.extra_points +
00175 loader->max_points;
00176
00177 FT_GlyphLoader_Adjust_Points( loader );
00178 }
00179 return error;
00180 }
00181
00182
00183
00184 static void
00185 FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader loader )
00186 {
00187 FT_GlyphLoad base = &loader->base;
00188 FT_GlyphLoad current = &loader->current;
00189
00190
00191 current->subglyphs = base->subglyphs + base->num_subglyphs;
00192 }
00193
00194
00195
00196
00197
00198
00199 FT_BASE_DEF( FT_Error )
00200 FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader,
00201 FT_UInt n_points,
00202 FT_UInt n_contours )
00203 {
00204 FT_Memory memory = loader->memory;
00205 FT_Error error = FT_Err_Ok;
00206 FT_Outline* base = &loader->base.outline;
00207 FT_Outline* current = &loader->current.outline;
00208 FT_Bool adjust = 0;
00209
00210 FT_UInt new_max, old_max;
00211
00212
00213
00214 new_max = base->n_points + current->n_points + n_points;
00215 old_max = loader->max_points;
00216
00217 if ( new_max > old_max )
00218 {
00219 new_max = FT_PAD_CEIL( new_max, 8 );
00220
00221 if ( new_max > FT_OUTLINE_POINTS_MAX )
00222 return FT_Err_Array_Too_Large;
00223
00224 if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
00225 FT_RENEW_ARRAY( base->tags, old_max, new_max ) )
00226 goto Exit;
00227
00228 if ( loader->use_extra )
00229 {
00230 if ( FT_RENEW_ARRAY( loader->base.extra_points,
00231 old_max * 2, new_max * 2 ) )
00232 goto Exit;
00233
00234 FT_ARRAY_MOVE( loader->base.extra_points + new_max,
00235 loader->base.extra_points + old_max,
00236 old_max );
00237
00238 loader->base.extra_points2 = loader->base.extra_points + new_max;
00239 }
00240
00241 adjust = 1;
00242 loader->max_points = new_max;
00243 }
00244
00245
00246 old_max = loader->max_contours;
00247 new_max = base->n_contours + current->n_contours +
00248 n_contours;
00249 if ( new_max > old_max )
00250 {
00251 new_max = FT_PAD_CEIL( new_max, 4 );
00252
00253 if ( new_max > FT_OUTLINE_CONTOURS_MAX )
00254 return FT_Err_Array_Too_Large;
00255
00256 if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
00257 goto Exit;
00258
00259 adjust = 1;
00260 loader->max_contours = new_max;
00261 }
00262
00263 if ( adjust )
00264 FT_GlyphLoader_Adjust_Points( loader );
00265
00266 Exit:
00267 return error;
00268 }
00269
00270
00271
00272
00273
00274
00275 FT_BASE_DEF( FT_Error )
00276 FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader,
00277 FT_UInt n_subs )
00278 {
00279 FT_Memory memory = loader->memory;
00280 FT_Error error = FT_Err_Ok;
00281 FT_UInt new_max, old_max;
00282
00283 FT_GlyphLoad base = &loader->base;
00284 FT_GlyphLoad current = &loader->current;
00285
00286
00287 new_max = base->num_subglyphs + current->num_subglyphs + n_subs;
00288 old_max = loader->max_subglyphs;
00289 if ( new_max > old_max )
00290 {
00291 new_max = FT_PAD_CEIL( new_max, 2 );
00292 if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) )
00293 goto Exit;
00294
00295 loader->max_subglyphs = new_max;
00296
00297 FT_GlyphLoader_Adjust_Subglyphs( loader );
00298 }
00299
00300 Exit:
00301 return error;
00302 }
00303
00304
00305
00306 FT_BASE_DEF( void )
00307 FT_GlyphLoader_Prepare( FT_GlyphLoader loader )
00308 {
00309 FT_GlyphLoad current = &loader->current;
00310
00311
00312 current->outline.n_points = 0;
00313 current->outline.n_contours = 0;
00314 current->num_subglyphs = 0;
00315
00316 FT_GlyphLoader_Adjust_Points ( loader );
00317 FT_GlyphLoader_Adjust_Subglyphs( loader );
00318 }
00319
00320
00321
00322 FT_BASE_DEF( void )
00323 FT_GlyphLoader_Add( FT_GlyphLoader loader )
00324 {
00325 FT_GlyphLoad base;
00326 FT_GlyphLoad current;
00327
00328 FT_UInt n_curr_contours;
00329 FT_UInt n_base_points;
00330 FT_UInt n;
00331
00332
00333 if ( !loader )
00334 return;
00335
00336 base = &loader->base;
00337 current = &loader->current;
00338
00339 n_curr_contours = current->outline.n_contours;
00340 n_base_points = base->outline.n_points;
00341
00342 base->outline.n_points =
00343 (short)( base->outline.n_points + current->outline.n_points );
00344 base->outline.n_contours =
00345 (short)( base->outline.n_contours + current->outline.n_contours );
00346
00347 base->num_subglyphs += current->num_subglyphs;
00348
00349
00350 for ( n = 0; n < n_curr_contours; n++ )
00351 current->outline.contours[n] =
00352 (short)( current->outline.contours[n] + n_base_points );
00353
00354
00355 FT_GlyphLoader_Prepare( loader );
00356 }
00357
00358
00359 FT_BASE_DEF( FT_Error )
00360 FT_GlyphLoader_CopyPoints( FT_GlyphLoader target,
00361 FT_GlyphLoader source )
00362 {
00363 FT_Error error;
00364 FT_UInt num_points = source->base.outline.n_points;
00365 FT_UInt num_contours = source->base.outline.n_contours;
00366
00367
00368 error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours );
00369 if ( !error )
00370 {
00371 FT_Outline* out = &target->base.outline;
00372 FT_Outline* in = &source->base.outline;
00373
00374
00375 FT_ARRAY_COPY( out->points, in->points,
00376 num_points );
00377 FT_ARRAY_COPY( out->tags, in->tags,
00378 num_points );
00379 FT_ARRAY_COPY( out->contours, in->contours,
00380 num_contours );
00381
00382
00383 if ( target->use_extra && source->use_extra )
00384 {
00385 FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points,
00386 num_points );
00387 FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2,
00388 num_points );
00389 }
00390
00391 out->n_points = (short)num_points;
00392 out->n_contours = (short)num_contours;
00393
00394 FT_GlyphLoader_Adjust_Points( target );
00395 }
00396
00397 return error;
00398 }
00399
00400
00401