| 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-2013 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 |
| 18 | 18 |
| 19 #include "../../include/ft2build.h" | 19 #include <ft2build.h> |
| 20 #include "../../include/freetype/internal/ftdebug.h" | 20 #include FT_INTERNAL_DEBUG_H |
| 21 #include "../../include/freetype/internal/ftobjs.h" | 21 #include FT_INTERNAL_OBJECTS_H |
| 22 #include "../../include/freetype/ftoutln.h" | 22 #include FT_OUTLINE_H |
| 23 #include "ftsmooth.h" | 23 #include "ftsmooth.h" |
| 24 #include "ftgrays.h" | 24 #include "ftgrays.h" |
| 25 #include "ftspic.h" | 25 #include "ftspic.h" |
| 26 | 26 |
| 27 #include "ftsmerrs.h" | 27 #include "ftsmerrs.h" |
| 28 | 28 |
| 29 | 29 |
| 30 /* initialize renderer -- init its raster */ | 30 /* initialize renderer -- init its raster */ |
| 31 static FT_Error | 31 static FT_Error |
| 32 ft_smooth_init( FT_Renderer render ) | 32 ft_smooth_init( FT_Renderer render ) |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 | 96 |
| 97 /* convert a slot's glyph image into a bitmap */ | 97 /* convert a slot's glyph image into a bitmap */ |
| 98 static FT_Error | 98 static FT_Error |
| 99 ft_smooth_render_generic( FT_Renderer render, | 99 ft_smooth_render_generic( FT_Renderer render, |
| 100 FT_GlyphSlot slot, | 100 FT_GlyphSlot slot, |
| 101 FT_Render_Mode mode, | 101 FT_Render_Mode mode, |
| 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 = &slot->outline; |
| 107 FT_Bitmap* bitmap = &slot->bitmap; |
| 108 FT_Memory memory = render->root.memory; |
| 107 FT_BBox cbox; | 109 FT_BBox cbox; |
| 110 FT_Pos x_shift = 0; |
| 111 FT_Pos y_shift = 0; |
| 112 FT_Pos x_left, y_top; |
| 108 FT_Pos width, height, pitch; | 113 FT_Pos width, height, pitch; |
| 109 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING | 114 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING |
| 110 FT_Pos height_org, width_org; | 115 FT_Pos height_org, width_org; |
| 111 #endif | 116 #endif |
| 112 FT_Bitmap* bitmap = &slot->bitmap; | |
| 113 FT_Memory memory = render->root.memory; | |
| 114 FT_Int hmul = mode == FT_RENDER_MODE_LCD; | 117 FT_Int hmul = mode == FT_RENDER_MODE_LCD; |
| 115 FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; | 118 FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; |
| 116 FT_Pos x_shift = 0; | |
| 117 FT_Pos y_shift = 0; | |
| 118 FT_Pos x_left, y_top; | |
| 119 | 119 |
| 120 FT_Raster_Params params; | 120 FT_Raster_Params params; |
| 121 | 121 |
| 122 FT_Bool have_translated_origin = FALSE; | 122 FT_Bool have_outline_shifted = FALSE; |
| 123 FT_Bool have_outline_shifted = FALSE; | 123 FT_Bool have_buffer = FALSE; |
| 124 FT_Bool have_buffer = FALSE; | |
| 125 | 124 |
| 126 | 125 |
| 127 /* check glyph image format */ | 126 /* check glyph image format */ |
| 128 if ( slot->format != render->glyph_format ) | 127 if ( slot->format != render->glyph_format ) |
| 129 { | 128 { |
| 130 error = FT_THROW( Invalid_Argument ); | 129 error = FT_THROW( Invalid_Argument ); |
| 131 goto Exit; | 130 goto Exit; |
| 132 } | 131 } |
| 133 | 132 |
| 134 /* check mode */ | 133 /* check mode */ |
| 135 if ( mode != required_mode ) | 134 if ( mode != required_mode ) |
| 136 { | 135 { |
| 137 error = FT_THROW( Cannot_Render_Glyph ); | 136 error = FT_THROW( Cannot_Render_Glyph ); |
| 138 goto Exit; | 137 goto Exit; |
| 139 } | 138 } |
| 140 | 139 |
| 141 outline = &slot->outline; | |
| 142 | |
| 143 /* translate the outline to the new origin if needed */ | |
| 144 if ( origin ) | 140 if ( origin ) |
| 145 { | 141 { |
| 146 FT_Outline_Translate( outline, origin->x, origin->y ); | 142 x_shift = origin->x; |
| 147 have_translated_origin = TRUE; | 143 y_shift = origin->y; |
| 148 } | 144 } |
| 149 | 145 |
| 150 /* compute the control box, and grid fit it */ | 146 /* compute the control box, and grid fit it */ |
| 147 /* taking into account the origin shift */ |
| 151 FT_Outline_Get_CBox( outline, &cbox ); | 148 FT_Outline_Get_CBox( outline, &cbox ); |
| 152 | 149 |
| 153 cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); | 150 cbox.xMin = FT_PIX_FLOOR( cbox.xMin + x_shift ); |
| 154 cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); | 151 cbox.yMin = FT_PIX_FLOOR( cbox.yMin + y_shift ); |
| 155 cbox.xMax = FT_PIX_CEIL( cbox.xMax ); | 152 cbox.xMax = FT_PIX_CEIL( cbox.xMax + x_shift ); |
| 156 cbox.yMax = FT_PIX_CEIL( cbox.yMax ); | 153 cbox.yMax = FT_PIX_CEIL( cbox.yMax + y_shift ); |
| 157 | 154 |
| 158 if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) | 155 x_shift -= cbox.xMin; |
| 159 { | 156 y_shift -= cbox.yMin; |
| 160 FT_ERROR(( "ft_smooth_render_generic: glyph too large:" | |
| 161 " xMin = %d, xMax = %d\n", | |
| 162 cbox.xMin >> 6, cbox.xMax >> 6 )); | |
| 163 error = FT_THROW( Raster_Overflow ); | |
| 164 goto Exit; | |
| 165 } | |
| 166 else | |
| 167 width = ( cbox.xMax - cbox.xMin ) >> 6; | |
| 168 | 157 |
| 169 if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) | 158 x_left = cbox.xMin >> 6; |
| 170 { | 159 y_top = cbox.yMax >> 6; |
| 171 FT_ERROR(( "ft_smooth_render_generic: glyph too large:" | 160 |
| 172 " yMin = %d, yMax = %d\n", | 161 width = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6; |
| 173 cbox.yMin >> 6, cbox.yMax >> 6 )); | 162 height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6; |
| 174 error = FT_THROW( Raster_Overflow ); | |
| 175 goto Exit; | |
| 176 } | |
| 177 else | |
| 178 height = ( cbox.yMax - cbox.yMin ) >> 6; | |
| 179 | 163 |
| 180 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING | 164 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING |
| 181 width_org = width; | 165 width_org = width; |
| 182 height_org = height; | 166 height_org = height; |
| 183 #endif | 167 #endif |
| 184 | 168 |
| 185 /* release old bitmap buffer */ | |
| 186 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) | |
| 187 { | |
| 188 FT_FREE( bitmap->buffer ); | |
| 189 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; | |
| 190 } | |
| 191 | |
| 192 /* allocate new one */ | |
| 193 pitch = width; | 169 pitch = width; |
| 194 if ( hmul ) | 170 if ( hmul ) |
| 195 { | 171 { |
| 196 width = width * 3; | 172 width *= 3; |
| 197 pitch = FT_PAD_CEIL( width, 4 ); | 173 pitch = FT_PAD_CEIL( width, 4 ); |
| 198 } | 174 } |
| 199 | 175 |
| 200 if ( vmul ) | 176 if ( vmul ) |
| 201 height *= 3; | 177 height *= 3; |
| 202 | 178 |
| 203 x_shift = (FT_Int) cbox.xMin; | |
| 204 y_shift = (FT_Int) cbox.yMin; | |
| 205 x_left = (FT_Int)( cbox.xMin >> 6 ); | |
| 206 y_top = (FT_Int)( cbox.yMax >> 6 ); | |
| 207 | |
| 208 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING | 179 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING |
| 209 | 180 |
| 210 if ( slot->library->lcd_filter_func ) | 181 if ( slot->library->lcd_filter_func ) |
| 211 { | 182 { |
| 212 FT_Int extra = slot->library->lcd_extra; | 183 FT_Int extra = slot->library->lcd_extra; |
| 213 | 184 |
| 214 | 185 |
| 215 if ( hmul ) | 186 if ( hmul ) |
| 216 { | 187 { |
| 217 x_shift -= 64 * ( extra >> 1 ); | 188 x_shift += 64 * ( extra >> 1 ); |
| 189 x_left -= extra >> 1; |
| 218 width += 3 * extra; | 190 width += 3 * extra; |
| 219 pitch = FT_PAD_CEIL( width, 4 ); | 191 pitch = FT_PAD_CEIL( width, 4 ); |
| 220 x_left -= extra >> 1; | |
| 221 } | 192 } |
| 222 | 193 |
| 223 if ( vmul ) | 194 if ( vmul ) |
| 224 { | 195 { |
| 225 y_shift -= 64 * ( extra >> 1 ); | 196 y_shift += 64 * ( extra >> 1 ); |
| 197 y_top += extra >> 1; |
| 226 height += 3 * extra; | 198 height += 3 * extra; |
| 227 y_top += extra >> 1; | |
| 228 } | 199 } |
| 229 } | 200 } |
| 230 | 201 |
| 231 #endif | 202 #endif |
| 232 | 203 |
| 233 #if FT_UINT_MAX > 0xFFFFU | 204 /* |
| 205 * XXX: on 16bit system, we return an error for huge bitmap |
| 206 * to prevent an overflow. |
| 207 */ |
| 208 if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX || |
| 209 x_left < FT_INT_MIN || y_top < FT_INT_MIN ) |
| 210 { |
| 211 error = FT_THROW( Invalid_Pixel_Size ); |
| 212 goto Exit; |
| 213 } |
| 234 | 214 |
| 235 /* Required check is (pitch * height < FT_ULONG_MAX), */ | 215 /* Required check is (pitch * height < FT_ULONG_MAX), */ |
| 236 /* but we care realistic cases only. Always pitch <= width. */ | 216 /* but we care realistic cases only. Always pitch <= width. */ |
| 237 if ( width > 0x7FFF || height > 0x7FFF ) | 217 if ( width > 0x7FFF || height > 0x7FFF ) |
| 238 { | 218 { |
| 239 FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n", | 219 FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n", |
| 240 width, height )); | 220 width, height )); |
| 241 error = FT_THROW( Raster_Overflow ); | 221 error = FT_THROW( Raster_Overflow ); |
| 242 goto Exit; | 222 goto Exit; |
| 243 } | 223 } |
| 244 | 224 |
| 245 #endif | 225 /* release old bitmap buffer */ |
| 226 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) |
| 227 { |
| 228 FT_FREE( bitmap->buffer ); |
| 229 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; |
| 230 } |
| 231 |
| 232 /* allocate new one */ |
| 233 if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) |
| 234 goto Exit; |
| 235 else |
| 236 have_buffer = TRUE; |
| 237 |
| 238 slot->internal->flags |= FT_GLYPH_OWN_BITMAP; |
| 239 |
| 240 slot->format = FT_GLYPH_FORMAT_BITMAP; |
| 241 slot->bitmap_left = (FT_Int)x_left; |
| 242 slot->bitmap_top = (FT_Int)y_top; |
| 246 | 243 |
| 247 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; | 244 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; |
| 248 bitmap->num_grays = 256; | 245 bitmap->num_grays = 256; |
| 249 bitmap->width = width; | 246 bitmap->width = width; |
| 250 bitmap->rows = height; | 247 bitmap->rows = height; |
| 251 bitmap->pitch = pitch; | 248 bitmap->pitch = pitch; |
| 252 | 249 |
| 253 /* translate outline to render it into the bitmap */ | 250 /* translate outline to render it into the bitmap */ |
| 254 FT_Outline_Translate( outline, -x_shift, -y_shift ); | 251 if ( x_shift || y_shift ) |
| 255 have_outline_shifted = TRUE; | 252 { |
| 256 | 253 FT_Outline_Translate( outline, x_shift, y_shift ); |
| 257 if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) | 254 have_outline_shifted = TRUE; |
| 258 goto Exit; | 255 } |
| 259 else | |
| 260 have_buffer = TRUE; | |
| 261 | |
| 262 slot->internal->flags |= FT_GLYPH_OWN_BITMAP; | |
| 263 | 256 |
| 264 /* set up parameters */ | 257 /* set up parameters */ |
| 265 params.target = bitmap; | 258 params.target = bitmap; |
| 266 params.source = outline; | 259 params.source = outline; |
| 267 params.flags = FT_RASTER_FLAG_AA; | 260 params.flags = FT_RASTER_FLAG_AA; |
| 268 | 261 |
| 269 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING | 262 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING |
| 270 | 263 |
| 271 /* implode outline if needed */ | 264 /* implode outline if needed */ |
| 272 { | 265 { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 write += pitch; | 352 write += pitch; |
| 360 | 353 |
| 361 ft_memcpy( write, read, pitch ); | 354 ft_memcpy( write, read, pitch ); |
| 362 write += pitch; | 355 write += pitch; |
| 363 read += pitch; | 356 read += pitch; |
| 364 } | 357 } |
| 365 } | 358 } |
| 366 | 359 |
| 367 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ | 360 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ |
| 368 | 361 |
| 369 /* | |
| 370 * XXX: on 16bit system, we return an error for huge bitmap | |
| 371 * to prevent an overflow. | |
| 372 */ | |
| 373 if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) | |
| 374 { | |
| 375 error = FT_THROW( Invalid_Pixel_Size ); | |
| 376 goto Exit; | |
| 377 } | |
| 378 | |
| 379 slot->format = FT_GLYPH_FORMAT_BITMAP; | |
| 380 slot->bitmap_left = (FT_Int)x_left; | |
| 381 slot->bitmap_top = (FT_Int)y_top; | |
| 382 | |
| 383 /* everything is fine; don't deallocate buffer */ | 362 /* everything is fine; don't deallocate buffer */ |
| 384 have_buffer = FALSE; | 363 have_buffer = FALSE; |
| 385 | 364 |
| 386 error = FT_Err_Ok; | 365 error = FT_Err_Ok; |
| 387 | 366 |
| 388 Exit: | 367 Exit: |
| 389 if ( have_outline_shifted ) | 368 if ( have_outline_shifted ) |
| 390 FT_Outline_Translate( outline, x_shift, y_shift ); | 369 FT_Outline_Translate( outline, -x_shift, -y_shift ); |
| 391 if ( have_translated_origin ) | |
| 392 FT_Outline_Translate( outline, -origin->x, -origin->y ); | |
| 393 if ( have_buffer ) | 370 if ( have_buffer ) |
| 394 { | 371 { |
| 395 FT_FREE( bitmap->buffer ); | 372 FT_FREE( bitmap->buffer ); |
| 396 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; | 373 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; |
| 397 } | 374 } |
| 398 | 375 |
| 399 return error; | 376 return error; |
| 400 } | 377 } |
| 401 | 378 |
| 402 | 379 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, | 502 (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, |
| 526 (FT_Renderer_TransformFunc)ft_smooth_transform, | 503 (FT_Renderer_TransformFunc)ft_smooth_transform, |
| 527 (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, | 504 (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, |
| 528 (FT_Renderer_SetModeFunc) ft_smooth_set_mode, | 505 (FT_Renderer_SetModeFunc) ft_smooth_set_mode, |
| 529 | 506 |
| 530 (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET | 507 (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET |
| 531 ) | 508 ) |
| 532 | 509 |
| 533 | 510 |
| 534 /* END */ | 511 /* END */ |
| OLD | NEW |