| OLD | NEW |
| 1 /***************************************************************************/ | 1 /***************************************************************************/ |
| 2 /* */ | 2 /* */ |
| 3 /* ftsmooth.c */ | 3 /* ftsmooth.c */ |
| 4 /* */ | 4 /* */ |
| 5 /* Anti-aliasing renderer interface (body). */ | 5 /* Anti-aliasing renderer interface (body). */ |
| 6 /* */ | 6 /* */ |
| 7 /* Copyright 2000-2006, 2009-2012 by */ | 7 /* Copyright 2000-2006, 2009-2013 by */ |
| 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
| 9 /* */ | 9 /* */ |
| 10 /* This file is part of the FreeType project, and may only be used, */ | 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 */ | 11 /* modified, and distributed under the terms of the FreeType project */ |
| 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
| 13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
| 14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
| 15 /* */ | 15 /* */ |
| 16 /***************************************************************************/ | 16 /***************************************************************************/ |
| 17 | 17 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 data ); | 54 data ); |
| 55 } | 55 } |
| 56 | 56 |
| 57 /* transform a given glyph image */ | 57 /* transform a given glyph image */ |
| 58 static FT_Error | 58 static FT_Error |
| 59 ft_smooth_transform( FT_Renderer render, | 59 ft_smooth_transform( FT_Renderer render, |
| 60 FT_GlyphSlot slot, | 60 FT_GlyphSlot slot, |
| 61 const FT_Matrix* matrix, | 61 const FT_Matrix* matrix, |
| 62 const FT_Vector* delta ) | 62 const FT_Vector* delta ) |
| 63 { | 63 { |
| 64 FT_Error error = Smooth_Err_Ok; | 64 FT_Error error = FT_Err_Ok; |
| 65 | 65 |
| 66 | 66 |
| 67 if ( slot->format != render->glyph_format ) | 67 if ( slot->format != render->glyph_format ) |
| 68 { | 68 { |
| 69 error = Smooth_Err_Invalid_Argument; | 69 error = FT_THROW( Invalid_Argument ); |
| 70 goto Exit; | 70 goto Exit; |
| 71 } | 71 } |
| 72 | 72 |
| 73 if ( matrix ) | 73 if ( matrix ) |
| 74 FT_Outline_Transform( &slot->outline, matrix ); | 74 FT_Outline_Transform( &slot->outline, matrix ); |
| 75 | 75 |
| 76 if ( delta ) | 76 if ( delta ) |
| 77 FT_Outline_Translate( &slot->outline, delta->x, delta->y ); | 77 FT_Outline_Translate( &slot->outline, delta->x, delta->y ); |
| 78 | 78 |
| 79 Exit: | 79 Exit: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 102 const FT_Vector* origin, | 102 const FT_Vector* origin, |
| 103 FT_Render_Mode required_mode ) | 103 FT_Render_Mode required_mode ) |
| 104 { | 104 { |
| 105 FT_Error error; | 105 FT_Error error; |
| 106 FT_Outline* outline = NULL; | 106 FT_Outline* outline = NULL; |
| 107 FT_BBox cbox; | 107 FT_BBox cbox; |
| 108 FT_Pos width, height, pitch; | 108 FT_Pos width, height, pitch; |
| 109 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING | 109 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING |
| 110 FT_Pos height_org, width_org; | 110 FT_Pos height_org, width_org; |
| 111 #endif | 111 #endif |
| 112 FT_Bitmap* bitmap; | 112 FT_Bitmap* bitmap = &slot->bitmap; |
| 113 FT_Memory memory; | 113 FT_Memory memory = render->root.memory; |
| 114 FT_Int hmul = mode == FT_RENDER_MODE_LCD; | 114 FT_Int hmul = mode == FT_RENDER_MODE_LCD; |
| 115 FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; | 115 FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; |
| 116 FT_Pos x_shift, y_shift, x_left, y_top; | 116 FT_Pos x_shift = 0; |
| 117 FT_Pos y_shift = 0; |
| 118 FT_Pos x_left, y_top; |
| 117 | 119 |
| 118 FT_Raster_Params params; | 120 FT_Raster_Params params; |
| 119 | 121 |
| 122 FT_Bool have_translated_origin = FALSE; |
| 123 FT_Bool have_outline_shifted = FALSE; |
| 124 FT_Bool have_buffer = FALSE; |
| 125 |
| 120 | 126 |
| 121 /* check glyph image format */ | 127 /* check glyph image format */ |
| 122 if ( slot->format != render->glyph_format ) | 128 if ( slot->format != render->glyph_format ) |
| 123 { | 129 { |
| 124 error = Smooth_Err_Invalid_Argument; | 130 error = FT_THROW( Invalid_Argument ); |
| 125 goto Exit; | 131 goto Exit; |
| 126 } | 132 } |
| 127 | 133 |
| 128 /* check mode */ | 134 /* check mode */ |
| 129 if ( mode != required_mode ) | 135 if ( mode != required_mode ) |
| 130 return Smooth_Err_Cannot_Render_Glyph; | 136 { |
| 137 error = FT_THROW( Cannot_Render_Glyph ); |
| 138 goto Exit; |
| 139 } |
| 131 | 140 |
| 132 outline = &slot->outline; | 141 outline = &slot->outline; |
| 133 | 142 |
| 134 /* translate the outline to the new origin if needed */ | 143 /* translate the outline to the new origin if needed */ |
| 135 if ( origin ) | 144 if ( origin ) |
| 145 { |
| 136 FT_Outline_Translate( outline, origin->x, origin->y ); | 146 FT_Outline_Translate( outline, origin->x, origin->y ); |
| 147 have_translated_origin = TRUE; |
| 148 } |
| 137 | 149 |
| 138 /* compute the control box, and grid fit it */ | 150 /* compute the control box, and grid fit it */ |
| 139 FT_Outline_Get_CBox( outline, &cbox ); | 151 FT_Outline_Get_CBox( outline, &cbox ); |
| 140 | 152 |
| 141 cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); | 153 cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); |
| 142 cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); | 154 cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); |
| 143 cbox.xMax = FT_PIX_CEIL( cbox.xMax ); | 155 cbox.xMax = FT_PIX_CEIL( cbox.xMax ); |
| 144 cbox.yMax = FT_PIX_CEIL( cbox.yMax ); | 156 cbox.yMax = FT_PIX_CEIL( cbox.yMax ); |
| 145 | 157 |
| 146 if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) | 158 if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) |
| 147 { | 159 { |
| 148 FT_ERROR(( "ft_smooth_render_generic: glyph too large:" | 160 FT_ERROR(( "ft_smooth_render_generic: glyph too large:" |
| 149 " xMin = %d, xMax = %d\n", | 161 " xMin = %d, xMax = %d\n", |
| 150 cbox.xMin >> 6, cbox.xMax >> 6 )); | 162 cbox.xMin >> 6, cbox.xMax >> 6 )); |
| 151 return Smooth_Err_Raster_Overflow; | 163 error = FT_THROW( Raster_Overflow ); |
| 164 goto Exit; |
| 152 } | 165 } |
| 153 else | 166 else |
| 154 width = ( cbox.xMax - cbox.xMin ) >> 6; | 167 width = ( cbox.xMax - cbox.xMin ) >> 6; |
| 155 | 168 |
| 156 if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) | 169 if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) |
| 157 { | 170 { |
| 158 FT_ERROR(( "ft_smooth_render_generic: glyph too large:" | 171 FT_ERROR(( "ft_smooth_render_generic: glyph too large:" |
| 159 " yMin = %d, yMax = %d\n", | 172 " yMin = %d, yMax = %d\n", |
| 160 cbox.yMin >> 6, cbox.yMax >> 6 )); | 173 cbox.yMin >> 6, cbox.yMax >> 6 )); |
| 161 return Smooth_Err_Raster_Overflow; | 174 error = FT_THROW( Raster_Overflow ); |
| 175 goto Exit; |
| 162 } | 176 } |
| 163 else | 177 else |
| 164 height = ( cbox.yMax - cbox.yMin ) >> 6; | 178 height = ( cbox.yMax - cbox.yMin ) >> 6; |
| 165 | 179 |
| 166 bitmap = &slot->bitmap; | |
| 167 memory = render->root.memory; | |
| 168 | |
| 169 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING | 180 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING |
| 170 width_org = width; | 181 width_org = width; |
| 171 height_org = height; | 182 height_org = height; |
| 172 #endif | 183 #endif |
| 173 | 184 |
| 174 /* release old bitmap buffer */ | 185 /* release old bitmap buffer */ |
| 175 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) | 186 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) |
| 176 { | 187 { |
| 177 FT_FREE( bitmap->buffer ); | 188 FT_FREE( bitmap->buffer ); |
| 178 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; | 189 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 y_shift -= 64 * ( extra >> 1 ); | 225 y_shift -= 64 * ( extra >> 1 ); |
| 215 height += 3 * extra; | 226 height += 3 * extra; |
| 216 y_top += extra >> 1; | 227 y_top += extra >> 1; |
| 217 } | 228 } |
| 218 } | 229 } |
| 219 | 230 |
| 220 #endif | 231 #endif |
| 221 | 232 |
| 222 #if FT_UINT_MAX > 0xFFFFU | 233 #if FT_UINT_MAX > 0xFFFFU |
| 223 | 234 |
| 224 /* Required check is ( pitch * height < FT_ULONG_MAX ), */ | 235 /* Required check is (pitch * height < FT_ULONG_MAX), */ |
| 225 /* but we care realistic cases only. Always pitch <= width. */ | 236 /* but we care realistic cases only. Always pitch <= width. */ |
| 226 if ( width > 0x7FFF || height > 0x7FFF ) | 237 if ( width > 0x7FFF || height > 0x7FFF ) |
| 227 { | 238 { |
| 228 FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n", | 239 FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n", |
| 229 width, height )); | 240 width, height )); |
| 230 return Smooth_Err_Raster_Overflow; | 241 error = FT_THROW( Raster_Overflow ); |
| 242 goto Exit; |
| 231 } | 243 } |
| 232 | 244 |
| 233 #endif | 245 #endif |
| 234 | 246 |
| 235 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; | 247 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; |
| 236 bitmap->num_grays = 256; | 248 bitmap->num_grays = 256; |
| 237 bitmap->width = width; | 249 bitmap->width = width; |
| 238 bitmap->rows = height; | 250 bitmap->rows = height; |
| 239 bitmap->pitch = pitch; | 251 bitmap->pitch = pitch; |
| 240 | 252 |
| 241 /* translate outline to render it into the bitmap */ | 253 /* translate outline to render it into the bitmap */ |
| 242 FT_Outline_Translate( outline, -x_shift, -y_shift ); | 254 FT_Outline_Translate( outline, -x_shift, -y_shift ); |
| 255 have_outline_shifted = TRUE; |
| 243 | 256 |
| 244 if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) | 257 if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) |
| 245 goto Exit; | 258 goto Exit; |
| 259 else |
| 260 have_buffer = TRUE; |
| 246 | 261 |
| 247 slot->internal->flags |= FT_GLYPH_OWN_BITMAP; | 262 slot->internal->flags |= FT_GLYPH_OWN_BITMAP; |
| 248 | 263 |
| 249 /* set up parameters */ | 264 /* set up parameters */ |
| 250 params.target = bitmap; | 265 params.target = bitmap; |
| 251 params.source = outline; | 266 params.source = outline; |
| 252 params.flags = FT_RASTER_FLAG_AA; | 267 params.flags = FT_RASTER_FLAG_AA; |
| 253 | 268 |
| 254 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING | 269 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING |
| 255 | 270 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 281 | 296 |
| 282 if ( hmul ) | 297 if ( hmul ) |
| 283 for ( vec = points; vec < points_end; vec++ ) | 298 for ( vec = points; vec < points_end; vec++ ) |
| 284 vec->x /= 3; | 299 vec->x /= 3; |
| 285 | 300 |
| 286 if ( vmul ) | 301 if ( vmul ) |
| 287 for ( vec = points; vec < points_end; vec++ ) | 302 for ( vec = points; vec < points_end; vec++ ) |
| 288 vec->y /= 3; | 303 vec->y /= 3; |
| 289 } | 304 } |
| 290 | 305 |
| 306 if ( error ) |
| 307 goto Exit; |
| 308 |
| 291 if ( slot->library->lcd_filter_func ) | 309 if ( slot->library->lcd_filter_func ) |
| 292 slot->library->lcd_filter_func( bitmap, mode, slot->library ); | 310 slot->library->lcd_filter_func( bitmap, mode, slot->library ); |
| 293 | 311 |
| 294 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ | 312 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ |
| 295 | 313 |
| 296 /* render outline into bitmap */ | 314 /* render outline into bitmap */ |
| 297 error = render->raster_render( render->raster, ¶ms ); | 315 error = render->raster_render( render->raster, ¶ms ); |
| 316 if ( error ) |
| 317 goto Exit; |
| 298 | 318 |
| 299 /* expand it horizontally */ | 319 /* expand it horizontally */ |
| 300 if ( hmul ) | 320 if ( hmul ) |
| 301 { | 321 { |
| 302 FT_Byte* line = bitmap->buffer; | 322 FT_Byte* line = bitmap->buffer; |
| 303 FT_UInt hh; | 323 FT_UInt hh; |
| 304 | 324 |
| 305 | 325 |
| 306 for ( hh = height_org; hh > 0; hh--, line += pitch ) | 326 for ( hh = height_org; hh > 0; hh--, line += pitch ) |
| 307 { | 327 { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 write += pitch; | 359 write += pitch; |
| 340 | 360 |
| 341 ft_memcpy( write, read, pitch ); | 361 ft_memcpy( write, read, pitch ); |
| 342 write += pitch; | 362 write += pitch; |
| 343 read += pitch; | 363 read += pitch; |
| 344 } | 364 } |
| 345 } | 365 } |
| 346 | 366 |
| 347 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ | 367 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ |
| 348 | 368 |
| 349 FT_Outline_Translate( outline, x_shift, y_shift ); | |
| 350 | |
| 351 /* | 369 /* |
| 352 * XXX: on 16bit system, we return an error for huge bitmap | 370 * XXX: on 16bit system, we return an error for huge bitmap |
| 353 * to prevent an overflow. | 371 * to prevent an overflow. |
| 354 */ | 372 */ |
| 355 if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) | 373 if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) |
| 356 return Smooth_Err_Invalid_Pixel_Size; | 374 { |
| 357 | 375 error = FT_THROW( Invalid_Pixel_Size ); |
| 358 if ( error ) | |
| 359 goto Exit; | 376 goto Exit; |
| 377 } |
| 360 | 378 |
| 361 slot->format = FT_GLYPH_FORMAT_BITMAP; | 379 slot->format = FT_GLYPH_FORMAT_BITMAP; |
| 362 slot->bitmap_left = (FT_Int)x_left; | 380 slot->bitmap_left = (FT_Int)x_left; |
| 363 slot->bitmap_top = (FT_Int)y_top; | 381 slot->bitmap_top = (FT_Int)y_top; |
| 364 | 382 |
| 383 /* everything is fine; don't deallocate buffer */ |
| 384 have_buffer = FALSE; |
| 385 |
| 386 error = FT_Err_Ok; |
| 387 |
| 365 Exit: | 388 Exit: |
| 366 if ( outline && origin ) | 389 if ( have_outline_shifted ) |
| 390 FT_Outline_Translate( outline, x_shift, y_shift ); |
| 391 if ( have_translated_origin ) |
| 367 FT_Outline_Translate( outline, -origin->x, -origin->y ); | 392 FT_Outline_Translate( outline, -origin->x, -origin->y ); |
| 393 if ( have_buffer ) |
| 394 { |
| 395 FT_FREE( bitmap->buffer ); |
| 396 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; |
| 397 } |
| 368 | 398 |
| 369 return error; | 399 return error; |
| 370 } | 400 } |
| 371 | 401 |
| 372 | 402 |
| 373 /* convert a slot's glyph image into a bitmap */ | 403 /* convert a slot's glyph image into a bitmap */ |
| 374 static FT_Error | 404 static FT_Error |
| 375 ft_smooth_render( FT_Renderer render, | 405 ft_smooth_render( FT_Renderer render, |
| 376 FT_GlyphSlot slot, | 406 FT_GlyphSlot slot, |
| 377 FT_Render_Mode mode, | 407 FT_Render_Mode mode, |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, | 525 (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, |
| 496 (FT_Renderer_TransformFunc)ft_smooth_transform, | 526 (FT_Renderer_TransformFunc)ft_smooth_transform, |
| 497 (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, | 527 (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, |
| 498 (FT_Renderer_SetModeFunc) ft_smooth_set_mode, | 528 (FT_Renderer_SetModeFunc) ft_smooth_set_mode, |
| 499 | 529 |
| 500 (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET | 530 (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET |
| 501 ) | 531 ) |
| 502 | 532 |
| 503 | 533 |
| 504 /* END */ | 534 /* END */ |
| OLD | NEW |