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 |