Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenftglyph.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* ftglyph.c */ 00004 /* */ 00005 /* FreeType convenience functions to handle glyphs (body). */ 00006 /* */ 00007 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007, 2008, 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 /* */ 00020 /* This file contains the definition of several convenience functions */ 00021 /* that can be used by client applications to easily retrieve glyph */ 00022 /* bitmaps and outlines from a given face. */ 00023 /* */ 00024 /* These functions should be optional if you are writing a font server */ 00025 /* or text layout engine on top of FreeType. However, they are pretty */ 00026 /* handy for many other simple uses of the library. */ 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 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00042 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00043 /* messages during execution. */ 00044 /* */ 00045 #undef FT_COMPONENT 00046 #define FT_COMPONENT trace_glyph 00047 00048 00049 /*************************************************************************/ 00050 /*************************************************************************/ 00051 /**** ****/ 00052 /**** FT_BitmapGlyph support ****/ 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 /* do lazy copying whenever possible */ 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, /* FT_Glyph_TransformFunc */ 00141 ft_bitmap_glyph_bbox, 00142 0 /* FT_Glyph_PrepareFunc */ 00143 ) 00144 00145 00146 /*************************************************************************/ 00147 /*************************************************************************/ 00148 /**** ****/ 00149 /**** FT_OutlineGlyph support ****/ 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 /* check format in glyph slot */ 00167 if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) 00168 { 00169 error = FT_Err_Invalid_Glyph_Format; 00170 goto Exit; 00171 } 00172 00173 /* allocate new outline */ 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 /**** FT_Glyph class and API ****/ 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 = NULL; 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 /* documentation is in ftglyph.h */ 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 /* check arguments */ 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 /* documentation is in ftglyph.h */ 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 /* if it is a bitmap, that's easy :-) */ 00372 if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) 00373 clazz = FT_BITMAP_GLYPH_CLASS_GET; 00374 00375 /* if it is an outline */ 00376 else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) 00377 clazz = FT_OUTLINE_GLYPH_CLASS_GET; 00378 00379 else 00380 { 00381 /* try to find a renderer that supports the glyph image format */ 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 /* create FT_Glyph object */ 00396 error = ft_new_glyph( library, clazz, &glyph ); 00397 if ( error ) 00398 goto Exit; 00399 00400 /* copy advance while converting it to 16.16 format */ 00401 glyph->advance.x = slot->advance.x << 10; 00402 glyph->advance.y = slot->advance.y << 10; 00403 00404 /* now import the image from the glyph slot */ 00405 error = clazz->glyph_init( glyph, slot ); 00406 00407 /* if an error occurred, destroy the glyph */ 00408 if ( error ) 00409 FT_Done_Glyph( glyph ); 00410 else 00411 *aglyph = glyph; 00412 00413 Exit: 00414 return error; 00415 } 00416 00417 00418 /* documentation is in ftglyph.h */ 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 /* transform glyph image */ 00437 clazz->glyph_transform( glyph, matrix, delta ); 00438 00439 /* transform advance vector */ 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 /* documentation is in ftglyph.h */ 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 /* retrieve bbox in 26.6 coordinates */ 00475 clazz->glyph_bbox( glyph, acbox ); 00476 00477 /* perform grid fitting if needed */ 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 /* convert to integer pixels if needed */ 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 /* documentation is in ftglyph.h */ 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 /* check argument */ 00524 if ( !the_glyph ) 00525 goto Bad; 00526 00527 /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ 00528 /* then calling FT_Render_Glyph_Internal() */ 00529 00530 glyph = *the_glyph; 00531 if ( !glyph ) 00532 goto Bad; 00533 00534 clazz = glyph->clazz; 00535 00536 /* when called with a bitmap glyph, do nothing and return successfully */ 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 /* create result bitmap glyph */ 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 /* if `origin' is set, translate the glyph image */ 00557 if ( origin ) 00558 FT_Glyph_Transform( glyph, 0, origin ); 00559 #else 00560 FT_UNUSED( origin ); 00561 #endif 00562 00563 /* prepare dummy slot for rendering */ 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 /* in case of success, copy the bitmap to the glyph bitmap */ 00584 error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy ); 00585 if ( error ) 00586 goto Exit; 00587 00588 /* copy advance */ 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 /* documentation is in ftglyph.h */ 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 /* END */ Generated on Mon May 28 2012 04:33:34 for ReactOS by
1.7.6.1
|