ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ftsmooth.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, &params );
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, &params );
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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.