Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenftgloadr.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* ftgloadr.c */ 00004 /* */ 00005 /* The FreeType glyph loader (body). */ 00006 /* */ 00007 /* Copyright 2002, 2003, 2004, 2005, 2006, 2010 by */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 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 /***** G L Y P H L O A D E R *****/ 00034 /***** *****/ 00035 /***** *****/ 00036 /*************************************************************************/ 00037 /*************************************************************************/ 00038 /*************************************************************************/ 00039 00040 /*************************************************************************/ 00041 /* */ 00042 /* The glyph loader is a simple object which is used to load a set of */ 00043 /* glyphs easily. It is critical for the correct loading of composites. */ 00044 /* */ 00045 /* Ideally, one can see it as a stack of abstract `glyph' objects. */ 00046 /* */ 00047 /* loader.base Is really the bottom of the stack. It describes a */ 00048 /* single glyph image made of the juxtaposition of */ 00049 /* several glyphs (those `in the stack'). */ 00050 /* */ 00051 /* loader.current Describes the top of the stack, on which a new */ 00052 /* glyph can be loaded. */ 00053 /* */ 00054 /* Rewind Clears the stack. */ 00055 /* Prepare Set up `loader.current' for addition of a new glyph */ 00056 /* image. */ 00057 /* Add Add the `current' glyph image to the `base' one, */ 00058 /* and prepare for another one. */ 00059 /* */ 00060 /* The glyph loader is now a base object. Each driver used to */ 00061 /* re-implement it in one way or the other, which wasted code and */ 00062 /* energy. */ 00063 /* */ 00064 /*************************************************************************/ 00065 00066 00067 /* create a new glyph loader */ 00068 FT_BASE_DEF( FT_Error ) 00069 FT_GlyphLoader_New( FT_Memory memory, 00070 FT_GlyphLoader *aloader ) 00071 { 00072 FT_GlyphLoader loader = NULL; 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 /* rewind the glyph loader - reset counters to 0 */ 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 /* reset the glyph loader, frees all allocated tables */ 00102 /* and starts from zero */ 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 /* delete a glyph loader */ 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 /* re-adjust the `current' outline fields */ 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 /* handle extra points table - if any */ 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 /* re-adjust the `current' subglyphs field */ 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 /* Ensure that we can add `n_points' and `n_contours' to our glyph. */ 00196 /* This function reallocates its outline tables if necessary. Note that */ 00197 /* it DOESN'T change the number of points within the loader! */ 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 /* check points & tags */ 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 /* check contours */ 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 /* Ensure that we can add `n_subglyphs' to our glyph. this function */ 00272 /* reallocates its subglyphs table if necessary. Note that it DOES */ 00273 /* NOT change the number of subglyphs within the loader! */ 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 /* prepare loader for the addition of a new glyph on top of the base one */ 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 /* add current glyph to the base image - and prepare for another */ 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 /* adjust contours count in newest outline */ 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 /* prepare for another new glyph image */ 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 /* do we need to copy the extra points? */ 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 /* END */ Generated on Fri May 25 2012 04:32:09 for ReactOS by
1.7.6.1
|