00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <ft2build.h>
00032 #include FT_GLYPH_H
00033 #include FT_OUTLINE_H
00034 #include FT_BITMAP_H
00035 #include FT_INTERNAL_OBJECTS_H
00036
00037 #include "basepic.h"
00038
00039
00040
00041
00042
00043
00044
00045 #undef FT_COMPONENT
00046 #define FT_COMPONENT trace_glyph
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 FT_CALLBACK_DEF( FT_Error )
00058 ft_bitmap_glyph_init( FT_Glyph bitmap_glyph,
00059 FT_GlyphSlot slot )
00060 {
00061 FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
00062 FT_Error error = FT_Err_Ok;
00063 FT_Library library = FT_GLYPH( glyph )->library;
00064
00065
00066 if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
00067 {
00068 error = FT_Err_Invalid_Glyph_Format;
00069 goto Exit;
00070 }
00071
00072 glyph->left = slot->bitmap_left;
00073 glyph->top = slot->bitmap_top;
00074
00075
00076 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
00077 {
00078 glyph->bitmap = slot->bitmap;
00079 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
00080 }
00081 else
00082 {
00083 FT_Bitmap_New( &glyph->bitmap );
00084 error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap );
00085 }
00086
00087 Exit:
00088 return error;
00089 }
00090
00091
00092 FT_CALLBACK_DEF( FT_Error )
00093 ft_bitmap_glyph_copy( FT_Glyph bitmap_source,
00094 FT_Glyph bitmap_target )
00095 {
00096 FT_Library library = bitmap_source->library;
00097 FT_BitmapGlyph source = (FT_BitmapGlyph)bitmap_source;
00098 FT_BitmapGlyph target = (FT_BitmapGlyph)bitmap_target;
00099
00100
00101 target->left = source->left;
00102 target->top = source->top;
00103
00104 return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap );
00105 }
00106
00107
00108 FT_CALLBACK_DEF( void )
00109 ft_bitmap_glyph_done( FT_Glyph bitmap_glyph )
00110 {
00111 FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
00112 FT_Library library = FT_GLYPH( glyph )->library;
00113
00114
00115 FT_Bitmap_Done( library, &glyph->bitmap );
00116 }
00117
00118
00119 FT_CALLBACK_DEF( void )
00120 ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph,
00121 FT_BBox* cbox )
00122 {
00123 FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
00124
00125
00126 cbox->xMin = glyph->left << 6;
00127 cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 );
00128 cbox->yMax = glyph->top << 6;
00129 cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 );
00130 }
00131
00132
00133 FT_DEFINE_GLYPH(ft_bitmap_glyph_class,
00134 sizeof ( FT_BitmapGlyphRec ),
00135 FT_GLYPH_FORMAT_BITMAP,
00136
00137 ft_bitmap_glyph_init,
00138 ft_bitmap_glyph_done,
00139 ft_bitmap_glyph_copy,
00140 0,
00141 ft_bitmap_glyph_bbox,
00142 0
00143 )
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 FT_CALLBACK_DEF( FT_Error )
00156 ft_outline_glyph_init( FT_Glyph outline_glyph,
00157 FT_GlyphSlot slot )
00158 {
00159 FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
00160 FT_Error error = FT_Err_Ok;
00161 FT_Library library = FT_GLYPH( glyph )->library;
00162 FT_Outline* source = &slot->outline;
00163 FT_Outline* target = &glyph->outline;
00164
00165
00166
00167 if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
00168 {
00169 error = FT_Err_Invalid_Glyph_Format;
00170 goto Exit;
00171 }
00172
00173
00174 error = FT_Outline_New( library, source->n_points, source->n_contours,
00175 &glyph->outline );
00176 if ( error )
00177 goto Exit;
00178
00179 FT_Outline_Copy( source, target );
00180
00181 Exit:
00182 return error;
00183 }
00184
00185
00186 FT_CALLBACK_DEF( void )
00187 ft_outline_glyph_done( FT_Glyph outline_glyph )
00188 {
00189 FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
00190
00191
00192 FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline );
00193 }
00194
00195
00196 FT_CALLBACK_DEF( FT_Error )
00197 ft_outline_glyph_copy( FT_Glyph outline_source,
00198 FT_Glyph outline_target )
00199 {
00200 FT_OutlineGlyph source = (FT_OutlineGlyph)outline_source;
00201 FT_OutlineGlyph target = (FT_OutlineGlyph)outline_target;
00202 FT_Error error;
00203 FT_Library library = FT_GLYPH( source )->library;
00204
00205
00206 error = FT_Outline_New( library, source->outline.n_points,
00207 source->outline.n_contours, &target->outline );
00208 if ( !error )
00209 FT_Outline_Copy( &source->outline, &target->outline );
00210
00211 return error;
00212 }
00213
00214
00215 FT_CALLBACK_DEF( void )
00216 ft_outline_glyph_transform( FT_Glyph outline_glyph,
00217 const FT_Matrix* matrix,
00218 const FT_Vector* delta )
00219 {
00220 FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
00221
00222
00223 if ( matrix )
00224 FT_Outline_Transform( &glyph->outline, matrix );
00225
00226 if ( delta )
00227 FT_Outline_Translate( &glyph->outline, delta->x, delta->y );
00228 }
00229
00230
00231 FT_CALLBACK_DEF( void )
00232 ft_outline_glyph_bbox( FT_Glyph outline_glyph,
00233 FT_BBox* bbox )
00234 {
00235 FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
00236
00237
00238 FT_Outline_Get_CBox( &glyph->outline, bbox );
00239 }
00240
00241
00242 FT_CALLBACK_DEF( FT_Error )
00243 ft_outline_glyph_prepare( FT_Glyph outline_glyph,
00244 FT_GlyphSlot slot )
00245 {
00246 FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
00247
00248
00249 slot->format = FT_GLYPH_FORMAT_OUTLINE;
00250 slot->outline = glyph->outline;
00251 slot->outline.flags &= ~FT_OUTLINE_OWNER;
00252
00253 return FT_Err_Ok;
00254 }
00255
00256
00257 FT_DEFINE_GLYPH( ft_outline_glyph_class,
00258 sizeof ( FT_OutlineGlyphRec ),
00259 FT_GLYPH_FORMAT_OUTLINE,
00260
00261 ft_outline_glyph_init,
00262 ft_outline_glyph_done,
00263 ft_outline_glyph_copy,
00264 ft_outline_glyph_transform,
00265 ft_outline_glyph_bbox,
00266 ft_outline_glyph_prepare
00267 )
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 static FT_Error
00279 ft_new_glyph( FT_Library library,
00280 const FT_Glyph_Class* clazz,
00281 FT_Glyph* aglyph )
00282 {
00283 FT_Memory memory = library->memory;
00284 FT_Error error;
00285 FT_Glyph glyph;
00286
00287
00288 *aglyph = 0;
00289
00290 if ( !FT_ALLOC( glyph, clazz->glyph_size ) )
00291 {
00292 glyph->library = library;
00293 glyph->clazz = clazz;
00294 glyph->format = clazz->glyph_format;
00295
00296 *aglyph = glyph;
00297 }
00298
00299 return error;
00300 }
00301
00302
00303
00304
00305 FT_EXPORT_DEF( FT_Error )
00306 FT_Glyph_Copy( FT_Glyph source,
00307 FT_Glyph *target )
00308 {
00309 FT_Glyph copy;
00310 FT_Error error;
00311 const FT_Glyph_Class* clazz;
00312
00313
00314
00315 if ( !target )
00316 {
00317 error = FT_Err_Invalid_Argument;
00318 goto Exit;
00319 }
00320
00321 *target = 0;
00322
00323 if ( !source || !source->clazz )
00324 {
00325 error = FT_Err_Invalid_Argument;
00326 goto Exit;
00327 }
00328
00329 clazz = source->clazz;
00330 error = ft_new_glyph( source->library, clazz, © );
00331 if ( error )
00332 goto Exit;
00333
00334 copy->advance = source->advance;
00335 copy->format = source->format;
00336
00337 if ( clazz->glyph_copy )
00338 error = clazz->glyph_copy( source, copy );
00339
00340 if ( error )
00341 FT_Done_Glyph( copy );
00342 else
00343 *target = copy;
00344
00345 Exit:
00346 return error;
00347 }
00348
00349
00350
00351
00352 FT_EXPORT_DEF( FT_Error )
00353 FT_Get_Glyph( FT_GlyphSlot slot,
00354 FT_Glyph *aglyph )
00355 {
00356 FT_Library library;
00357 FT_Error error;
00358 FT_Glyph glyph;
00359
00360 const FT_Glyph_Class* clazz = 0;
00361
00362
00363 if ( !slot )
00364 return FT_Err_Invalid_Slot_Handle;
00365
00366 library = slot->library;
00367
00368 if ( !aglyph )
00369 return FT_Err_Invalid_Argument;
00370
00371
00372 if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
00373 clazz = FT_BITMAP_GLYPH_CLASS_GET;
00374
00375
00376 else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
00377 clazz = FT_OUTLINE_GLYPH_CLASS_GET;
00378
00379 else
00380 {
00381
00382 FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 );
00383
00384
00385 if ( render )
00386 clazz = &render->glyph_class;
00387 }
00388
00389 if ( !clazz )
00390 {
00391 error = FT_Err_Invalid_Glyph_Format;
00392 goto Exit;
00393 }
00394
00395
00396 error = ft_new_glyph( library, clazz, &glyph );
00397 if ( error )
00398 goto Exit;
00399
00400
00401 glyph->advance.x = slot->advance.x << 10;
00402 glyph->advance.y = slot->advance.y << 10;
00403
00404
00405 error = clazz->glyph_init( glyph, slot );
00406
00407
00408 if ( error )
00409 FT_Done_Glyph( glyph );
00410 else
00411 *aglyph = glyph;
00412
00413 Exit:
00414 return error;
00415 }
00416
00417
00418
00419
00420 FT_EXPORT_DEF( FT_Error )
00421 FT_Glyph_Transform( FT_Glyph glyph,
00422 FT_Matrix* matrix,
00423 FT_Vector* delta )
00424 {
00425 const FT_Glyph_Class* clazz;
00426 FT_Error error = FT_Err_Ok;
00427
00428
00429 if ( !glyph || !glyph->clazz )
00430 error = FT_Err_Invalid_Argument;
00431 else
00432 {
00433 clazz = glyph->clazz;
00434 if ( clazz->glyph_transform )
00435 {
00436
00437 clazz->glyph_transform( glyph, matrix, delta );
00438
00439
00440 if ( matrix )
00441 FT_Vector_Transform( &glyph->advance, matrix );
00442 }
00443 else
00444 error = FT_Err_Invalid_Glyph_Format;
00445 }
00446 return error;
00447 }
00448
00449
00450
00451
00452 FT_EXPORT_DEF( void )
00453 FT_Glyph_Get_CBox( FT_Glyph glyph,
00454 FT_UInt bbox_mode,
00455 FT_BBox *acbox )
00456 {
00457 const FT_Glyph_Class* clazz;
00458
00459
00460 if ( !acbox )
00461 return;
00462
00463 acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0;
00464
00465 if ( !glyph || !glyph->clazz )
00466 return;
00467 else
00468 {
00469 clazz = glyph->clazz;
00470 if ( !clazz->glyph_bbox )
00471 return;
00472 else
00473 {
00474
00475 clazz->glyph_bbox( glyph, acbox );
00476
00477
00478 if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT ||
00479 bbox_mode == FT_GLYPH_BBOX_PIXELS )
00480 {
00481 acbox->xMin = FT_PIX_FLOOR( acbox->xMin );
00482 acbox->yMin = FT_PIX_FLOOR( acbox->yMin );
00483 acbox->xMax = FT_PIX_CEIL( acbox->xMax );
00484 acbox->yMax = FT_PIX_CEIL( acbox->yMax );
00485 }
00486
00487
00488 if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE ||
00489 bbox_mode == FT_GLYPH_BBOX_PIXELS )
00490 {
00491 acbox->xMin >>= 6;
00492 acbox->yMin >>= 6;
00493 acbox->xMax >>= 6;
00494 acbox->yMax >>= 6;
00495 }
00496 }
00497 }
00498 return;
00499 }
00500
00501
00502
00503
00504 FT_EXPORT_DEF( FT_Error )
00505 FT_Glyph_To_Bitmap( FT_Glyph* the_glyph,
00506 FT_Render_Mode render_mode,
00507 FT_Vector* origin,
00508 FT_Bool destroy )
00509 {
00510 FT_GlyphSlotRec dummy;
00511 FT_GlyphSlot_InternalRec dummy_internal;
00512 FT_Error error = FT_Err_Ok;
00513 FT_Glyph glyph;
00514 FT_BitmapGlyph bitmap = NULL;
00515
00516 const FT_Glyph_Class* clazz;
00517
00518 #ifdef FT_CONFIG_OPTION_PIC
00519 FT_Library library = FT_GLYPH( glyph )->library;
00520 #endif
00521
00522
00523
00524 if ( !the_glyph )
00525 goto Bad;
00526
00527
00528
00529
00530 glyph = *the_glyph;
00531 if ( !glyph )
00532 goto Bad;
00533
00534 clazz = glyph->clazz;
00535
00536
00537 if ( clazz == FT_BITMAP_GLYPH_CLASS_GET )
00538 goto Exit;
00539
00540 if ( !clazz || !clazz->glyph_prepare )
00541 goto Bad;
00542
00543 FT_MEM_ZERO( &dummy, sizeof ( dummy ) );
00544 FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) );
00545 dummy.internal = &dummy_internal;
00546 dummy.library = glyph->library;
00547 dummy.format = clazz->glyph_format;
00548
00549
00550 error = ft_new_glyph( glyph->library, FT_BITMAP_GLYPH_CLASS_GET,
00551 (FT_Glyph*)(void*)&bitmap );
00552 if ( error )
00553 goto Exit;
00554
00555 #if 1
00556
00557 if ( origin )
00558 FT_Glyph_Transform( glyph, 0, origin );
00559 #else
00560 FT_UNUSED( origin );
00561 #endif
00562
00563
00564 error = clazz->glyph_prepare( glyph, &dummy );
00565 if ( !error )
00566 error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
00567
00568 #if 1
00569 if ( !destroy && origin )
00570 {
00571 FT_Vector v;
00572
00573
00574 v.x = -origin->x;
00575 v.y = -origin->y;
00576 FT_Glyph_Transform( glyph, 0, &v );
00577 }
00578 #endif
00579
00580 if ( error )
00581 goto Exit;
00582
00583
00584 error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy );
00585 if ( error )
00586 goto Exit;
00587
00588
00589 bitmap->root.advance = glyph->advance;
00590
00591 if ( destroy )
00592 FT_Done_Glyph( glyph );
00593
00594 *the_glyph = FT_GLYPH( bitmap );
00595
00596 Exit:
00597 if ( error && bitmap )
00598 FT_Done_Glyph( FT_GLYPH( bitmap ) );
00599
00600 return error;
00601
00602 Bad:
00603 error = FT_Err_Invalid_Argument;
00604 goto Exit;
00605 }
00606
00607
00608
00609
00610 FT_EXPORT_DEF( void )
00611 FT_Done_Glyph( FT_Glyph glyph )
00612 {
00613 if ( glyph )
00614 {
00615 FT_Memory memory = glyph->library->memory;
00616 const FT_Glyph_Class* clazz = glyph->clazz;
00617
00618
00619 if ( clazz->glyph_done )
00620 clazz->glyph_done( glyph );
00621
00622 FT_FREE( glyph );
00623 }
00624 }
00625
00626
00627