1 /***************************************************************************/ 2 /* */ 3 /* ftsmooth.c */ 4 /* */ 5 /* Anti-aliasing renderer interface (body). */ 6 /* */ 7 /* Copyright 2000-2001, 2002 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* */ 10 /* This file is part of the FreeType project, and may only be used, */ 11 /* modified, and distributed under the terms of the FreeType project */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13 /* this file you indicate that you have read the license and */ 14 /* understand and accept it fully. */ 15 /* */ 16 /***************************************************************************/ 17 18 19 #include <ft2build.h> 20 #include FT_INTERNAL_OBJECTS_H 21 #include FT_OUTLINE_H 22 #include "ftsmooth.h" 23 #include "ftgrays.h" 24 25 #include "ftsmerrs.h" 26 27 28 /* initialize renderer -- init its raster */ 29 static FT_Error 30 ft_smooth_init( FT_Renderer render ) 31 { 32 FT_Library library = FT_MODULE_LIBRARY( render ); 33 34 35 render->clazz->raster_class->raster_reset( render->raster, 36 library->raster_pool, 37 library->raster_pool_size ); 38 39 return 0; 40 } 41 42 43 /* sets render-specific mode */ 44 static FT_Error 45 ft_smooth_set_mode( FT_Renderer render, 46 FT_ULong mode_tag, 47 FT_Pointer data ) 48 { 49 /* we simply pass it to the raster */ 50 return render->clazz->raster_class->raster_set_mode( render->raster, 51 mode_tag, 52 data ); 53 } 54 55 /* transform a given glyph image */ 56 static FT_Error 57 ft_smooth_transform( FT_Renderer render, 58 FT_GlyphSlot slot, 59 FT_Matrix* matrix, 60 FT_Vector* delta ) 61 { 62 FT_Error error = Smooth_Err_Ok; 63 64 65 if ( slot->format != render->glyph_format ) 66 { 67 error = Smooth_Err_Invalid_Argument; 68 goto Exit; 69 } 70 71 if ( matrix ) 72 FT_Outline_Transform( &slot->outline, matrix ); 73 74 if ( delta ) 75 FT_Outline_Translate( &slot->outline, delta->x, delta->y ); 76 77 Exit: 78 return error; 79 } 80 81 82 /* return the glyph's control box */ 83 static void 84 ft_smooth_get_cbox( FT_Renderer render, 85 FT_GlyphSlot slot, 86 FT_BBox* cbox ) 87 { 88 FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); 89 90 if ( slot->format == render->glyph_format ) 91 FT_Outline_Get_CBox( &slot->outline, cbox ); 92 } 93 94 95 /* convert a slot's glyph image into a bitmap */ 96 static FT_Error 97 ft_smooth_render_generic( FT_Renderer render, 98 FT_GlyphSlot slot, 99 FT_Render_Mode mode, 100 FT_Vector* origin, 101 FT_Render_Mode required_mode, 102 FT_Int hmul, 103 FT_Int vmul ) 104 { 105 FT_Error error; 106 FT_Outline* outline = NULL; 107 FT_BBox cbox; 108 FT_UInt width, height, pitch; 109 FT_Bitmap* bitmap; 110 FT_Memory memory; 111 112 FT_Raster_Params params; 113 114 115 /* check glyph image format */ 116 if ( slot->format != render->glyph_format ) 117 { 118 error = Smooth_Err_Invalid_Argument; 119 goto Exit; 120 } 121 122 /* check mode */ 123 if ( mode != required_mode ) 124 return Smooth_Err_Cannot_Render_Glyph; 125 126 outline = &slot->outline; 127 128 /* translate the outline to the new origin if needed */ 129 if ( origin ) 130 FT_Outline_Translate( outline, origin->x, origin->y ); 131 132 /* compute the control box, and grid fit it */ 133 FT_Outline_Get_CBox( outline, &cbox ); 134 135 cbox.xMin &= -64; 136 cbox.yMin &= -64; 137 cbox.xMax = ( cbox.xMax + 63 ) & -64; 138 cbox.yMax = ( cbox.yMax + 63 ) & -64; 139 140 width = ( cbox.xMax - cbox.xMin ) >> 6; 141 height = ( cbox.yMax - cbox.yMin ) >> 6; 142 bitmap = &slot->bitmap; 143 memory = render->root.memory; 144 145 /* release old bitmap buffer */ 146 if ( slot->flags & FT_GLYPH_OWN_BITMAP ) 147 { 148 FT_FREE( bitmap->buffer ); 149 slot->flags &= ~FT_GLYPH_OWN_BITMAP; 150 } 151 152 /* allocate new one, depends on pixel format */ 153 pitch = width; 154 if ( hmul ) 155 { 156 width = width * hmul; 157 pitch = ( width + 3 ) & -4; 158 } 159 160 if ( vmul ) 161 height *= vmul; 162 163 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; 164 bitmap->num_grays = 256; 165 bitmap->width = width; 166 bitmap->rows = height; 167 bitmap->pitch = pitch; 168 169 if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) 170 goto Exit; 171 172 slot->flags |= FT_GLYPH_OWN_BITMAP; 173 174 /* translate outline to render it into the bitmap */ 175 FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); 176 177 /* set up parameters */ 178 params.target = bitmap; 179 params.source = outline; 180 params.flags = FT_RASTER_FLAG_AA; 181 182 /* implode outline if needed */ 183 { 184 FT_Int n; 185 FT_Vector* vec; 186 187 188 if ( hmul ) 189 for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) 190 vec->x *= hmul; 191 192 if ( vmul ) 193 for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) 194 vec->y *= vmul; 195 } 196 197 /* render outline into the bitmap */ 198 error = render->raster_render( render->raster, ¶ms ); 199 200 /* deflate outline if needed */ 201 { 202 FT_Int n; 203 FT_Vector* vec; 204 205 206 if ( hmul ) 207 for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) 208 vec->x /= hmul; 209 210 if ( vmul ) 211 for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) 212 vec->y /= vmul; 213 } 214 215 FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); 216 217 if ( error ) 218 goto Exit; 219 220 slot->format = FT_GLYPH_FORMAT_BITMAP; 221 slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); 222 slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 ); 223 224 Exit: 225 if ( outline && origin ) 226 FT_Outline_Translate( outline, -origin->x, -origin->y ); 227 228 return error; 229 } 230 231 232 /* convert a slot's glyph image into a bitmap */ 233 static FT_Error 234 ft_smooth_render( FT_Renderer render, 235 FT_GlyphSlot slot, 236 FT_Render_Mode mode, 237 FT_Vector* origin ) 238 { 239 return ft_smooth_render_generic( render, slot, mode, origin, 240 FT_RENDER_MODE_NORMAL, 241 0, 0 ); 242 } 243 244 245 /* convert a slot's glyph image into a horizontal LCD bitmap */ 246 static FT_Error 247 ft_smooth_render_lcd( FT_Renderer render, 248 FT_GlyphSlot slot, 249 FT_Render_Mode mode, 250 FT_Vector* origin ) 251 { 252 FT_Error error; 253 254 error = ft_smooth_render_generic( render, slot, mode, origin, 255 FT_RENDER_MODE_LCD, 256 3, 0 ); 257 if ( !error ) 258 slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD; 259 260 return error; 261 } 262 263 264 /* convert a slot's glyph image into a vertical LCD bitmap */ 265 static FT_Error 266 ft_smooth_render_lcd_v( FT_Renderer render, 267 FT_GlyphSlot slot, 268 FT_Render_Mode mode, 269 FT_Vector* origin ) 270 { 271 FT_Error error; 272 273 error = ft_smooth_render_generic( render, slot, mode, origin, 274 FT_RENDER_MODE_LCD_V, 275 0, 3 ); 276 if ( !error ) 277 slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V; 278 279 return error; 280 } 281 282 283 FT_CALLBACK_TABLE_DEF 284 const FT_Renderer_Class ft_smooth_renderer_class = 285 { 286 { 287 ft_module_renderer, 288 sizeof( FT_RendererRec ), 289 290 "smooth", 291 0x10000L, 292 0x20000L, 293 294 0, /* module specific interface */ 295 296 (FT_Module_Constructor)ft_smooth_init, 297 (FT_Module_Destructor) 0, 298 (FT_Module_Requester) 0 299 }, 300 301 FT_GLYPH_FORMAT_OUTLINE, 302 303 (FT_Renderer_RenderFunc) ft_smooth_render, 304 (FT_Renderer_TransformFunc)ft_smooth_transform, 305 (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, 306 (FT_Renderer_SetModeFunc) ft_smooth_set_mode, 307 308 (FT_Raster_Funcs*) &ft_grays_raster 309 }; 310 311 312 FT_CALLBACK_TABLE_DEF 313 const FT_Renderer_Class ft_smooth_lcd_renderer_class = 314 { 315 { 316 ft_module_renderer, 317 sizeof( FT_RendererRec ), 318 319 "smooth-lcd", 320 0x10000L, 321 0x20000L, 322 323 0, /* module specific interface */ 324 325 (FT_Module_Constructor)ft_smooth_init, 326 (FT_Module_Destructor) 0, 327 (FT_Module_Requester) 0 328 }, 329 330 FT_GLYPH_FORMAT_OUTLINE, 331 332 (FT_Renderer_RenderFunc) ft_smooth_render_lcd, 333 (FT_Renderer_TransformFunc)ft_smooth_transform, 334 (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, 335 (FT_Renderer_SetModeFunc) ft_smooth_set_mode, 336 337 (FT_Raster_Funcs*) &ft_grays_raster 338 }; 339 340 341 342 FT_CALLBACK_TABLE_DEF 343 const FT_Renderer_Class ft_smooth_lcdv_renderer_class = 344 { 345 { 346 ft_module_renderer, 347 sizeof( FT_RendererRec ), 348 349 "smooth-lcdv", 350 0x10000L, 351 0x20000L, 352 353 0, /* module specific interface */ 354 355 (FT_Module_Constructor)ft_smooth_init, 356 (FT_Module_Destructor) 0, 357 (FT_Module_Requester) 0 358 }, 359 360 FT_GLYPH_FORMAT_OUTLINE, 361 362 (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, 363 (FT_Renderer_TransformFunc)ft_smooth_transform, 364 (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, 365 (FT_Renderer_SetModeFunc) ft_smooth_set_mode, 366 367 (FT_Raster_Funcs*) &ft_grays_raster 368 }; 369 370 371 /* END */ 372