Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenftsmooth.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* ftsmooth.c */ 00004 /* */ 00005 /* Anti-aliasing renderer interface (body). */ 00006 /* */ 00007 /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 by */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 00015 /* */ 00016 /***************************************************************************/ 00017 00018 00019 #include <ft2build.h> 00020 #include FT_INTERNAL_DEBUG_H 00021 #include FT_INTERNAL_OBJECTS_H 00022 #include FT_OUTLINE_H 00023 #include "ftsmooth.h" 00024 #include "ftgrays.h" 00025 #include "ftspic.h" 00026 00027 #include "ftsmerrs.h" 00028 00029 00030 /* initialize renderer -- init its raster */ 00031 static FT_Error 00032 ft_smooth_init( FT_Renderer render ) 00033 { 00034 FT_Library library = FT_MODULE_LIBRARY( render ); 00035 00036 00037 render->clazz->raster_class->raster_reset( render->raster, 00038 library->raster_pool, 00039 library->raster_pool_size ); 00040 00041 return 0; 00042 } 00043 00044 00045 /* sets render-specific mode */ 00046 static FT_Error 00047 ft_smooth_set_mode( FT_Renderer render, 00048 FT_ULong mode_tag, 00049 FT_Pointer data ) 00050 { 00051 /* we simply pass it to the raster */ 00052 return render->clazz->raster_class->raster_set_mode( render->raster, 00053 mode_tag, 00054 data ); 00055 } 00056 00057 /* transform a given glyph image */ 00058 static FT_Error 00059 ft_smooth_transform( FT_Renderer render, 00060 FT_GlyphSlot slot, 00061 const FT_Matrix* matrix, 00062 const FT_Vector* delta ) 00063 { 00064 FT_Error error = Smooth_Err_Ok; 00065 00066 00067 if ( slot->format != render->glyph_format ) 00068 { 00069 error = Smooth_Err_Invalid_Argument; 00070 goto Exit; 00071 } 00072 00073 if ( matrix ) 00074 FT_Outline_Transform( &slot->outline, matrix ); 00075 00076 if ( delta ) 00077 FT_Outline_Translate( &slot->outline, delta->x, delta->y ); 00078 00079 Exit: 00080 return error; 00081 } 00082 00083 00084 /* return the glyph's control box */ 00085 static void 00086 ft_smooth_get_cbox( FT_Renderer render, 00087 FT_GlyphSlot slot, 00088 FT_BBox* cbox ) 00089 { 00090 FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); 00091 00092 if ( slot->format == render->glyph_format ) 00093 FT_Outline_Get_CBox( &slot->outline, cbox ); 00094 } 00095 00096 00097 /* convert a slot's glyph image into a bitmap */ 00098 static FT_Error 00099 ft_smooth_render_generic( FT_Renderer render, 00100 FT_GlyphSlot slot, 00101 FT_Render_Mode mode, 00102 const FT_Vector* origin, 00103 FT_Render_Mode required_mode ) 00104 { 00105 FT_Error error; 00106 FT_Outline* outline = NULL; 00107 FT_BBox cbox; 00108 FT_UInt width, height, height_org, width_org, pitch; 00109 FT_Bitmap* bitmap; 00110 FT_Memory memory; 00111 FT_Int hmul = mode == FT_RENDER_MODE_LCD; 00112 FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; 00113 FT_Pos x_shift, y_shift, x_left, y_top; 00114 00115 FT_Raster_Params params; 00116 00117 00118 /* check glyph image format */ 00119 if ( slot->format != render->glyph_format ) 00120 { 00121 error = Smooth_Err_Invalid_Argument; 00122 goto Exit; 00123 } 00124 00125 /* check mode */ 00126 if ( mode != required_mode ) 00127 return Smooth_Err_Cannot_Render_Glyph; 00128 00129 outline = &slot->outline; 00130 00131 /* translate the outline to the new origin if needed */ 00132 if ( origin ) 00133 FT_Outline_Translate( outline, origin->x, origin->y ); 00134 00135 /* compute the control box, and grid fit it */ 00136 FT_Outline_Get_CBox( outline, &cbox ); 00137 00138 cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); 00139 cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); 00140 cbox.xMax = FT_PIX_CEIL( cbox.xMax ); 00141 cbox.yMax = FT_PIX_CEIL( cbox.yMax ); 00142 00143 if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) 00144 { 00145 FT_ERROR(( "ft_smooth_render_generic: glyph too large:" 00146 " xMin = %d, xMax = %d\n", 00147 cbox.xMin >> 6, cbox.xMax >> 6 )); 00148 return Smooth_Err_Raster_Overflow; 00149 } 00150 else 00151 width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); 00152 00153 if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) 00154 { 00155 FT_ERROR(( "ft_smooth_render_generic: glyph too large:" 00156 " yMin = %d, yMax = %d\n", 00157 cbox.yMin >> 6, cbox.yMax >> 6 )); 00158 return Smooth_Err_Raster_Overflow; 00159 } 00160 else 00161 height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); 00162 00163 bitmap = &slot->bitmap; 00164 memory = render->root.memory; 00165 00166 width_org = width; 00167 height_org = height; 00168 00169 /* release old bitmap buffer */ 00170 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) 00171 { 00172 FT_FREE( bitmap->buffer ); 00173 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; 00174 } 00175 00176 /* allocate new one */ 00177 pitch = width; 00178 if ( hmul ) 00179 { 00180 width = width * 3; 00181 pitch = FT_PAD_CEIL( width, 4 ); 00182 } 00183 00184 if ( vmul ) 00185 height *= 3; 00186 00187 x_shift = (FT_Int) cbox.xMin; 00188 y_shift = (FT_Int) cbox.yMin; 00189 x_left = (FT_Int)( cbox.xMin >> 6 ); 00190 y_top = (FT_Int)( cbox.yMax >> 6 ); 00191 00192 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING 00193 00194 if ( slot->library->lcd_filter_func ) 00195 { 00196 FT_Int extra = slot->library->lcd_extra; 00197 00198 00199 if ( hmul ) 00200 { 00201 x_shift -= 64 * ( extra >> 1 ); 00202 width += 3 * extra; 00203 pitch = FT_PAD_CEIL( width, 4 ); 00204 x_left -= extra >> 1; 00205 } 00206 00207 if ( vmul ) 00208 { 00209 y_shift -= 64 * ( extra >> 1 ); 00210 height += 3 * extra; 00211 y_top += extra >> 1; 00212 } 00213 } 00214 00215 #endif 00216 00217 #if FT_UINT_MAX > 0xFFFFU 00218 00219 /* Required check is ( pitch * height < FT_ULONG_MAX ), */ 00220 /* but we care realistic cases only. Always pitch <= width. */ 00221 if ( width > 0x7FFFU || height > 0x7FFFU ) 00222 { 00223 FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n", 00224 width, height )); 00225 return Smooth_Err_Raster_Overflow; 00226 } 00227 00228 #endif 00229 00230 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; 00231 bitmap->num_grays = 256; 00232 bitmap->width = width; 00233 bitmap->rows = height; 00234 bitmap->pitch = pitch; 00235 00236 /* translate outline to render it into the bitmap */ 00237 FT_Outline_Translate( outline, -x_shift, -y_shift ); 00238 00239 if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) 00240 goto Exit; 00241 00242 slot->internal->flags |= FT_GLYPH_OWN_BITMAP; 00243 00244 /* set up parameters */ 00245 params.target = bitmap; 00246 params.source = outline; 00247 params.flags = FT_RASTER_FLAG_AA; 00248 00249 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING 00250 00251 /* implode outline if needed */ 00252 { 00253 FT_Vector* points = outline->points; 00254 FT_Vector* points_end = points + outline->n_points; 00255 FT_Vector* vec; 00256 00257 00258 if ( hmul ) 00259 for ( vec = points; vec < points_end; vec++ ) 00260 vec->x *= 3; 00261 00262 if ( vmul ) 00263 for ( vec = points; vec < points_end; vec++ ) 00264 vec->y *= 3; 00265 } 00266 00267 /* render outline into the bitmap */ 00268 error = render->raster_render( render->raster, ¶ms ); 00269 00270 /* deflate outline if needed */ 00271 { 00272 FT_Vector* points = outline->points; 00273 FT_Vector* points_end = points + outline->n_points; 00274 FT_Vector* vec; 00275 00276 00277 if ( hmul ) 00278 for ( vec = points; vec < points_end; vec++ ) 00279 vec->x /= 3; 00280 00281 if ( vmul ) 00282 for ( vec = points; vec < points_end; vec++ ) 00283 vec->y /= 3; 00284 } 00285 00286 if ( slot->library->lcd_filter_func ) 00287 slot->library->lcd_filter_func( bitmap, mode, slot->library ); 00288 00289 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ 00290 00291 /* render outline into bitmap */ 00292 error = render->raster_render( render->raster, ¶ms ); 00293 00294 /* expand it horizontally */ 00295 if ( hmul ) 00296 { 00297 FT_Byte* line = bitmap->buffer; 00298 FT_UInt hh; 00299 00300 00301 for ( hh = height_org; hh > 0; hh--, line += pitch ) 00302 { 00303 FT_UInt xx; 00304 FT_Byte* end = line + width; 00305 00306 00307 for ( xx = width_org; xx > 0; xx-- ) 00308 { 00309 FT_UInt pixel = line[xx-1]; 00310 00311 00312 end[-3] = (FT_Byte)pixel; 00313 end[-2] = (FT_Byte)pixel; 00314 end[-1] = (FT_Byte)pixel; 00315 end -= 3; 00316 } 00317 } 00318 } 00319 00320 /* expand it vertically */ 00321 if ( vmul ) 00322 { 00323 FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch; 00324 FT_Byte* write = bitmap->buffer; 00325 FT_UInt hh; 00326 00327 00328 for ( hh = height_org; hh > 0; hh-- ) 00329 { 00330 ft_memcpy( write, read, pitch ); 00331 write += pitch; 00332 00333 ft_memcpy( write, read, pitch ); 00334 write += pitch; 00335 00336 ft_memcpy( write, read, pitch ); 00337 write += pitch; 00338 read += pitch; 00339 } 00340 } 00341 00342 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ 00343 00344 FT_Outline_Translate( outline, x_shift, y_shift ); 00345 00346 /* 00347 * XXX: on 16bit system, we return an error for huge bitmap 00348 * to prevent an overflow. 00349 */ 00350 if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) 00351 return Smooth_Err_Invalid_Pixel_Size; 00352 00353 if ( error ) 00354 goto Exit; 00355 00356 slot->format = FT_GLYPH_FORMAT_BITMAP; 00357 slot->bitmap_left = (FT_Int)x_left; 00358 slot->bitmap_top = (FT_Int)y_top; 00359 00360 Exit: 00361 if ( outline && origin ) 00362 FT_Outline_Translate( outline, -origin->x, -origin->y ); 00363 00364 return error; 00365 } 00366 00367 00368 /* convert a slot's glyph image into a bitmap */ 00369 static FT_Error 00370 ft_smooth_render( FT_Renderer render, 00371 FT_GlyphSlot slot, 00372 FT_Render_Mode mode, 00373 const FT_Vector* origin ) 00374 { 00375 if ( mode == FT_RENDER_MODE_LIGHT ) 00376 mode = FT_RENDER_MODE_NORMAL; 00377 00378 return ft_smooth_render_generic( render, slot, mode, origin, 00379 FT_RENDER_MODE_NORMAL ); 00380 } 00381 00382 00383 /* convert a slot's glyph image into a horizontal LCD bitmap */ 00384 static FT_Error 00385 ft_smooth_render_lcd( FT_Renderer render, 00386 FT_GlyphSlot slot, 00387 FT_Render_Mode mode, 00388 const FT_Vector* origin ) 00389 { 00390 FT_Error error; 00391 00392 error = ft_smooth_render_generic( render, slot, mode, origin, 00393 FT_RENDER_MODE_LCD ); 00394 if ( !error ) 00395 slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD; 00396 00397 return error; 00398 } 00399 00400 00401 /* convert a slot's glyph image into a vertical LCD bitmap */ 00402 static FT_Error 00403 ft_smooth_render_lcd_v( FT_Renderer render, 00404 FT_GlyphSlot slot, 00405 FT_Render_Mode mode, 00406 const FT_Vector* origin ) 00407 { 00408 FT_Error error; 00409 00410 error = ft_smooth_render_generic( render, slot, mode, origin, 00411 FT_RENDER_MODE_LCD_V ); 00412 if ( !error ) 00413 slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V; 00414 00415 return error; 00416 } 00417 00418 00419 FT_DEFINE_RENDERER(ft_smooth_renderer_class, 00420 00421 FT_MODULE_RENDERER, 00422 sizeof( FT_RendererRec ), 00423 00424 "smooth", 00425 0x10000L, 00426 0x20000L, 00427 00428 0, /* module specific interface */ 00429 00430 (FT_Module_Constructor)ft_smooth_init, 00431 (FT_Module_Destructor) 0, 00432 (FT_Module_Requester) 0 00433 , 00434 00435 FT_GLYPH_FORMAT_OUTLINE, 00436 00437 (FT_Renderer_RenderFunc) ft_smooth_render, 00438 (FT_Renderer_TransformFunc)ft_smooth_transform, 00439 (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, 00440 (FT_Renderer_SetModeFunc) ft_smooth_set_mode, 00441 00442 (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET 00443 ) 00444 00445 00446 FT_DEFINE_RENDERER(ft_smooth_lcd_renderer_class, 00447 00448 FT_MODULE_RENDERER, 00449 sizeof( FT_RendererRec ), 00450 00451 "smooth-lcd", 00452 0x10000L, 00453 0x20000L, 00454 00455 0, /* module specific interface */ 00456 00457 (FT_Module_Constructor)ft_smooth_init, 00458 (FT_Module_Destructor) 0, 00459 (FT_Module_Requester) 0 00460 , 00461 00462 FT_GLYPH_FORMAT_OUTLINE, 00463 00464 (FT_Renderer_RenderFunc) ft_smooth_render_lcd, 00465 (FT_Renderer_TransformFunc)ft_smooth_transform, 00466 (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, 00467 (FT_Renderer_SetModeFunc) ft_smooth_set_mode, 00468 00469 (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET 00470 ) 00471 00472 FT_DEFINE_RENDERER(ft_smooth_lcdv_renderer_class, 00473 00474 FT_MODULE_RENDERER, 00475 sizeof( FT_RendererRec ), 00476 00477 "smooth-lcdv", 00478 0x10000L, 00479 0x20000L, 00480 00481 0, /* module specific interface */ 00482 00483 (FT_Module_Constructor)ft_smooth_init, 00484 (FT_Module_Destructor) 0, 00485 (FT_Module_Requester) 0 00486 , 00487 00488 FT_GLYPH_FORMAT_OUTLINE, 00489 00490 (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, 00491 (FT_Renderer_TransformFunc)ft_smooth_transform, 00492 (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, 00493 (FT_Renderer_SetModeFunc) ft_smooth_set_mode, 00494 00495 (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET 00496 ) 00497 00498 00499 /* END */ Generated on Sun May 27 2012 04:34:02 for ReactOS by
1.7.6.1
|