1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* ftrend1.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* The FreeType glyph rasterizer interface (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 1996-2001, 2002 by */ 8*37da2899SCharles.Forsyth /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9*37da2899SCharles.Forsyth /* */ 10*37da2899SCharles.Forsyth /* This file is part of the FreeType project, and may only be used, */ 11*37da2899SCharles.Forsyth /* modified, and distributed under the terms of the FreeType project */ 12*37da2899SCharles.Forsyth /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13*37da2899SCharles.Forsyth /* this file you indicate that you have read the license and */ 14*37da2899SCharles.Forsyth /* understand and accept it fully. */ 15*37da2899SCharles.Forsyth /* */ 16*37da2899SCharles.Forsyth /***************************************************************************/ 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsyth #include <ft2build.h> 20*37da2899SCharles.Forsyth #include FT_INTERNAL_OBJECTS_H 21*37da2899SCharles.Forsyth #include FT_OUTLINE_H 22*37da2899SCharles.Forsyth #include "ftrend1.h" 23*37da2899SCharles.Forsyth #include "ftraster.h" 24*37da2899SCharles.Forsyth 25*37da2899SCharles.Forsyth #include "rasterrs.h" 26*37da2899SCharles.Forsyth 27*37da2899SCharles.Forsyth 28*37da2899SCharles.Forsyth /* initialize renderer -- init its raster */ 29*37da2899SCharles.Forsyth static FT_Error ft_raster1_init(FT_Renderer render)30*37da2899SCharles.Forsyth ft_raster1_init( FT_Renderer render ) 31*37da2899SCharles.Forsyth { 32*37da2899SCharles.Forsyth FT_Library library = FT_MODULE_LIBRARY( render ); 33*37da2899SCharles.Forsyth 34*37da2899SCharles.Forsyth 35*37da2899SCharles.Forsyth render->clazz->raster_class->raster_reset( render->raster, 36*37da2899SCharles.Forsyth library->raster_pool, 37*37da2899SCharles.Forsyth library->raster_pool_size ); 38*37da2899SCharles.Forsyth 39*37da2899SCharles.Forsyth return Raster_Err_Ok; 40*37da2899SCharles.Forsyth } 41*37da2899SCharles.Forsyth 42*37da2899SCharles.Forsyth 43*37da2899SCharles.Forsyth /* set render-specific mode */ 44*37da2899SCharles.Forsyth static FT_Error ft_raster1_set_mode(FT_Renderer render,FT_ULong mode_tag,FT_Pointer data)45*37da2899SCharles.Forsyth ft_raster1_set_mode( FT_Renderer render, 46*37da2899SCharles.Forsyth FT_ULong mode_tag, 47*37da2899SCharles.Forsyth FT_Pointer data ) 48*37da2899SCharles.Forsyth { 49*37da2899SCharles.Forsyth /* we simply pass it to the raster */ 50*37da2899SCharles.Forsyth return render->clazz->raster_class->raster_set_mode( render->raster, 51*37da2899SCharles.Forsyth mode_tag, 52*37da2899SCharles.Forsyth data ); 53*37da2899SCharles.Forsyth } 54*37da2899SCharles.Forsyth 55*37da2899SCharles.Forsyth 56*37da2899SCharles.Forsyth /* transform a given glyph image */ 57*37da2899SCharles.Forsyth static FT_Error ft_raster1_transform(FT_Renderer render,FT_GlyphSlot slot,FT_Matrix * matrix,FT_Vector * delta)58*37da2899SCharles.Forsyth ft_raster1_transform( FT_Renderer render, 59*37da2899SCharles.Forsyth FT_GlyphSlot slot, 60*37da2899SCharles.Forsyth FT_Matrix* matrix, 61*37da2899SCharles.Forsyth FT_Vector* delta ) 62*37da2899SCharles.Forsyth { 63*37da2899SCharles.Forsyth FT_Error error = Raster_Err_Ok; 64*37da2899SCharles.Forsyth 65*37da2899SCharles.Forsyth 66*37da2899SCharles.Forsyth if ( slot->format != render->glyph_format ) 67*37da2899SCharles.Forsyth { 68*37da2899SCharles.Forsyth error = Raster_Err_Invalid_Argument; 69*37da2899SCharles.Forsyth goto Exit; 70*37da2899SCharles.Forsyth } 71*37da2899SCharles.Forsyth 72*37da2899SCharles.Forsyth if ( matrix ) 73*37da2899SCharles.Forsyth FT_Outline_Transform( &slot->outline, matrix ); 74*37da2899SCharles.Forsyth 75*37da2899SCharles.Forsyth if ( delta ) 76*37da2899SCharles.Forsyth FT_Outline_Translate( &slot->outline, delta->x, delta->y ); 77*37da2899SCharles.Forsyth 78*37da2899SCharles.Forsyth Exit: 79*37da2899SCharles.Forsyth return error; 80*37da2899SCharles.Forsyth } 81*37da2899SCharles.Forsyth 82*37da2899SCharles.Forsyth 83*37da2899SCharles.Forsyth /* return the glyph's control box */ 84*37da2899SCharles.Forsyth static void ft_raster1_get_cbox(FT_Renderer render,FT_GlyphSlot slot,FT_BBox * cbox)85*37da2899SCharles.Forsyth ft_raster1_get_cbox( FT_Renderer render, 86*37da2899SCharles.Forsyth FT_GlyphSlot slot, 87*37da2899SCharles.Forsyth FT_BBox* cbox ) 88*37da2899SCharles.Forsyth { 89*37da2899SCharles.Forsyth FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); 90*37da2899SCharles.Forsyth 91*37da2899SCharles.Forsyth if ( slot->format == render->glyph_format ) 92*37da2899SCharles.Forsyth FT_Outline_Get_CBox( &slot->outline, cbox ); 93*37da2899SCharles.Forsyth } 94*37da2899SCharles.Forsyth 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth /* convert a slot's glyph image into a bitmap */ 97*37da2899SCharles.Forsyth static FT_Error ft_raster1_render(FT_Renderer render,FT_GlyphSlot slot,FT_Render_Mode mode,FT_Vector * origin)98*37da2899SCharles.Forsyth ft_raster1_render( FT_Renderer render, 99*37da2899SCharles.Forsyth FT_GlyphSlot slot, 100*37da2899SCharles.Forsyth FT_Render_Mode mode, 101*37da2899SCharles.Forsyth FT_Vector* origin ) 102*37da2899SCharles.Forsyth { 103*37da2899SCharles.Forsyth FT_Error error; 104*37da2899SCharles.Forsyth FT_Outline* outline; 105*37da2899SCharles.Forsyth FT_BBox cbox; 106*37da2899SCharles.Forsyth FT_UInt width, height, pitch; 107*37da2899SCharles.Forsyth FT_Bitmap* bitmap; 108*37da2899SCharles.Forsyth FT_Memory memory; 109*37da2899SCharles.Forsyth 110*37da2899SCharles.Forsyth FT_Raster_Params params; 111*37da2899SCharles.Forsyth 112*37da2899SCharles.Forsyth 113*37da2899SCharles.Forsyth /* check glyph image format */ 114*37da2899SCharles.Forsyth if ( slot->format != render->glyph_format ) 115*37da2899SCharles.Forsyth { 116*37da2899SCharles.Forsyth error = Raster_Err_Invalid_Argument; 117*37da2899SCharles.Forsyth goto Exit; 118*37da2899SCharles.Forsyth } 119*37da2899SCharles.Forsyth 120*37da2899SCharles.Forsyth /* check rendering mode */ 121*37da2899SCharles.Forsyth if ( mode != FT_RENDER_MODE_MONO ) 122*37da2899SCharles.Forsyth { 123*37da2899SCharles.Forsyth /* raster1 is only capable of producing monochrome bitmaps */ 124*37da2899SCharles.Forsyth if ( render->clazz == &ft_raster1_renderer_class ) 125*37da2899SCharles.Forsyth return Raster_Err_Cannot_Render_Glyph; 126*37da2899SCharles.Forsyth } 127*37da2899SCharles.Forsyth else 128*37da2899SCharles.Forsyth { 129*37da2899SCharles.Forsyth /* raster5 is only capable of producing 5-gray-levels bitmaps */ 130*37da2899SCharles.Forsyth if ( render->clazz == &ft_raster5_renderer_class ) 131*37da2899SCharles.Forsyth return Raster_Err_Cannot_Render_Glyph; 132*37da2899SCharles.Forsyth } 133*37da2899SCharles.Forsyth 134*37da2899SCharles.Forsyth outline = &slot->outline; 135*37da2899SCharles.Forsyth 136*37da2899SCharles.Forsyth /* translate the outline to the new origin if needed */ 137*37da2899SCharles.Forsyth if ( origin ) 138*37da2899SCharles.Forsyth FT_Outline_Translate( outline, origin->x, origin->y ); 139*37da2899SCharles.Forsyth 140*37da2899SCharles.Forsyth /* compute the control box, and grid fit it */ 141*37da2899SCharles.Forsyth FT_Outline_Get_CBox( outline, &cbox ); 142*37da2899SCharles.Forsyth 143*37da2899SCharles.Forsyth cbox.xMin &= -64; 144*37da2899SCharles.Forsyth cbox.yMin &= -64; 145*37da2899SCharles.Forsyth cbox.xMax = ( cbox.xMax + 63 ) & -64; 146*37da2899SCharles.Forsyth cbox.yMax = ( cbox.yMax + 63 ) & -64; 147*37da2899SCharles.Forsyth 148*37da2899SCharles.Forsyth width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); 149*37da2899SCharles.Forsyth height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); 150*37da2899SCharles.Forsyth bitmap = &slot->bitmap; 151*37da2899SCharles.Forsyth memory = render->root.memory; 152*37da2899SCharles.Forsyth 153*37da2899SCharles.Forsyth /* release old bitmap buffer */ 154*37da2899SCharles.Forsyth if ( slot->flags & FT_GLYPH_OWN_BITMAP ) 155*37da2899SCharles.Forsyth { 156*37da2899SCharles.Forsyth FT_FREE( bitmap->buffer ); 157*37da2899SCharles.Forsyth slot->flags &= ~FT_GLYPH_OWN_BITMAP; 158*37da2899SCharles.Forsyth } 159*37da2899SCharles.Forsyth 160*37da2899SCharles.Forsyth /* allocate new one, depends on pixel format */ 161*37da2899SCharles.Forsyth if ( !( mode & FT_RENDER_MODE_MONO ) ) 162*37da2899SCharles.Forsyth { 163*37da2899SCharles.Forsyth /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ 164*37da2899SCharles.Forsyth pitch = ( width + 3 ) & -4; 165*37da2899SCharles.Forsyth bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; 166*37da2899SCharles.Forsyth bitmap->num_grays = 256; 167*37da2899SCharles.Forsyth } 168*37da2899SCharles.Forsyth else 169*37da2899SCharles.Forsyth { 170*37da2899SCharles.Forsyth pitch = ( ( width + 15 ) >> 4 ) << 1; 171*37da2899SCharles.Forsyth bitmap->pixel_mode = FT_PIXEL_MODE_MONO; 172*37da2899SCharles.Forsyth } 173*37da2899SCharles.Forsyth 174*37da2899SCharles.Forsyth bitmap->width = width; 175*37da2899SCharles.Forsyth bitmap->rows = height; 176*37da2899SCharles.Forsyth bitmap->pitch = pitch; 177*37da2899SCharles.Forsyth 178*37da2899SCharles.Forsyth if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) 179*37da2899SCharles.Forsyth goto Exit; 180*37da2899SCharles.Forsyth 181*37da2899SCharles.Forsyth slot->flags |= FT_GLYPH_OWN_BITMAP; 182*37da2899SCharles.Forsyth 183*37da2899SCharles.Forsyth /* translate outline to render it into the bitmap */ 184*37da2899SCharles.Forsyth FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); 185*37da2899SCharles.Forsyth 186*37da2899SCharles.Forsyth /* set up parameters */ 187*37da2899SCharles.Forsyth params.target = bitmap; 188*37da2899SCharles.Forsyth params.source = outline; 189*37da2899SCharles.Forsyth params.flags = 0; 190*37da2899SCharles.Forsyth 191*37da2899SCharles.Forsyth if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY ) 192*37da2899SCharles.Forsyth params.flags |= FT_RASTER_FLAG_AA; 193*37da2899SCharles.Forsyth 194*37da2899SCharles.Forsyth /* render outline into the bitmap */ 195*37da2899SCharles.Forsyth error = render->raster_render( render->raster, ¶ms ); 196*37da2899SCharles.Forsyth 197*37da2899SCharles.Forsyth FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); 198*37da2899SCharles.Forsyth 199*37da2899SCharles.Forsyth if ( error ) 200*37da2899SCharles.Forsyth goto Exit; 201*37da2899SCharles.Forsyth 202*37da2899SCharles.Forsyth slot->format = FT_GLYPH_FORMAT_BITMAP; 203*37da2899SCharles.Forsyth slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); 204*37da2899SCharles.Forsyth slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 ); 205*37da2899SCharles.Forsyth 206*37da2899SCharles.Forsyth Exit: 207*37da2899SCharles.Forsyth return error; 208*37da2899SCharles.Forsyth } 209*37da2899SCharles.Forsyth 210*37da2899SCharles.Forsyth 211*37da2899SCharles.Forsyth FT_CALLBACK_TABLE_DEF 212*37da2899SCharles.Forsyth const FT_Renderer_Class ft_raster1_renderer_class = 213*37da2899SCharles.Forsyth { 214*37da2899SCharles.Forsyth { 215*37da2899SCharles.Forsyth ft_module_renderer, 216*37da2899SCharles.Forsyth sizeof( FT_RendererRec ), 217*37da2899SCharles.Forsyth 218*37da2899SCharles.Forsyth "raster1", 219*37da2899SCharles.Forsyth 0x10000L, 220*37da2899SCharles.Forsyth 0x20000L, 221*37da2899SCharles.Forsyth 222*37da2899SCharles.Forsyth 0, /* module specific interface */ 223*37da2899SCharles.Forsyth 224*37da2899SCharles.Forsyth (FT_Module_Constructor)ft_raster1_init, 225*37da2899SCharles.Forsyth (FT_Module_Destructor) 0, 226*37da2899SCharles.Forsyth (FT_Module_Requester) 0 227*37da2899SCharles.Forsyth }, 228*37da2899SCharles.Forsyth 229*37da2899SCharles.Forsyth FT_GLYPH_FORMAT_OUTLINE, 230*37da2899SCharles.Forsyth 231*37da2899SCharles.Forsyth (FT_Renderer_RenderFunc) ft_raster1_render, 232*37da2899SCharles.Forsyth (FT_Renderer_TransformFunc)ft_raster1_transform, 233*37da2899SCharles.Forsyth (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, 234*37da2899SCharles.Forsyth (FT_Renderer_SetModeFunc) ft_raster1_set_mode, 235*37da2899SCharles.Forsyth 236*37da2899SCharles.Forsyth (FT_Raster_Funcs*) &ft_standard_raster 237*37da2899SCharles.Forsyth }; 238*37da2899SCharles.Forsyth 239*37da2899SCharles.Forsyth 240*37da2899SCharles.Forsyth /* This renderer is _NOT_ part of the default modules; you will need */ 241*37da2899SCharles.Forsyth /* to register it by hand in your application. It should only be */ 242*37da2899SCharles.Forsyth /* used for backwards-compatibility with FT 1.x anyway. */ 243*37da2899SCharles.Forsyth /* */ 244*37da2899SCharles.Forsyth FT_CALLBACK_TABLE_DEF 245*37da2899SCharles.Forsyth const FT_Renderer_Class ft_raster5_renderer_class = 246*37da2899SCharles.Forsyth { 247*37da2899SCharles.Forsyth { 248*37da2899SCharles.Forsyth ft_module_renderer, 249*37da2899SCharles.Forsyth sizeof( FT_RendererRec ), 250*37da2899SCharles.Forsyth 251*37da2899SCharles.Forsyth "raster5", 252*37da2899SCharles.Forsyth 0x10000L, 253*37da2899SCharles.Forsyth 0x20000L, 254*37da2899SCharles.Forsyth 255*37da2899SCharles.Forsyth 0, /* module specific interface */ 256*37da2899SCharles.Forsyth 257*37da2899SCharles.Forsyth (FT_Module_Constructor)ft_raster1_init, 258*37da2899SCharles.Forsyth (FT_Module_Destructor) 0, 259*37da2899SCharles.Forsyth (FT_Module_Requester) 0 260*37da2899SCharles.Forsyth }, 261*37da2899SCharles.Forsyth 262*37da2899SCharles.Forsyth FT_GLYPH_FORMAT_OUTLINE, 263*37da2899SCharles.Forsyth 264*37da2899SCharles.Forsyth (FT_Renderer_RenderFunc) ft_raster1_render, 265*37da2899SCharles.Forsyth (FT_Renderer_TransformFunc)ft_raster1_transform, 266*37da2899SCharles.Forsyth (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, 267*37da2899SCharles.Forsyth (FT_Renderer_SetModeFunc) ft_raster1_set_mode, 268*37da2899SCharles.Forsyth 269*37da2899SCharles.Forsyth (FT_Raster_Funcs*) &ft_standard_raster 270*37da2899SCharles.Forsyth }; 271*37da2899SCharles.Forsyth 272*37da2899SCharles.Forsyth 273*37da2899SCharles.Forsyth /* END */ 274