1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  ftsmooth.c                                                             */
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*    Anti-aliasing renderer interface (body).                             */
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  Copyright 2000-2006, 2009-2013 by                                      */
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  This file is part of the FreeType project, and may only be used,       */
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  modified, and distributed under the terms of the FreeType project      */
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  this file you indicate that you have read the license and              */
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  understand and accept it fully.                                        */
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h"
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h"
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftobjs.h"
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftoutln.h"
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftsmooth.h"
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftgrays.h"
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftspic.h"
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftsmerrs.h"
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* initialize renderer -- init its raster */
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ft_smooth_init( FT_Renderer  render )
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Library  library = FT_MODULE_LIBRARY( render );
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    render->clazz->raster_class->raster_reset( render->raster,
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                               library->raster_pool,
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                               library->raster_pool_size );
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* sets render-specific mode */
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ft_smooth_set_mode( FT_Renderer  render,
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      FT_ULong     mode_tag,
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      FT_Pointer   data )
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* we simply pass it to the raster */
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return render->clazz->raster_class->raster_set_mode( render->raster,
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                         mode_tag,
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                         data );
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* transform a given glyph image */
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ft_smooth_transform( FT_Renderer       render,
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       FT_GlyphSlot      slot,
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       const FT_Matrix*  matrix,
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       const FT_Vector*  delta )
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error  error = FT_Err_Ok;
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( slot->format != render->glyph_format )
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = FT_THROW( Invalid_Argument );
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( matrix )
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Outline_Transform( &slot->outline, matrix );
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( delta )
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Outline_Translate( &slot->outline, delta->x, delta->y );
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Exit:
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* return the glyph's control box */
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static void
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ft_smooth_get_cbox( FT_Renderer   render,
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      FT_GlyphSlot  slot,
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      FT_BBox*      cbox )
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_MEM_ZERO( cbox, sizeof ( *cbox ) );
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( slot->format == render->glyph_format )
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Outline_Get_CBox( &slot->outline, cbox );
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* convert a slot's glyph image into a bitmap */
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ft_smooth_render_generic( FT_Renderer       render,
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            FT_GlyphSlot      slot,
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            FT_Render_Mode    mode,
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            const FT_Vector*  origin,
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            FT_Render_Mode    required_mode )
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error     error;
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Outline*  outline = NULL;
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_BBox      cbox;
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pos       width, height, pitch;
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pos       height_org, width_org;
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Bitmap*   bitmap  = &slot->bitmap;
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory    memory  = render->root.memory;
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Int       hmul    = mode == FT_RENDER_MODE_LCD;
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Int       vmul    = mode == FT_RENDER_MODE_LCD_V;
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pos       x_shift = 0;
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pos       y_shift = 0;
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pos       x_left, y_top;
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Raster_Params  params;
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Bool  have_translated_origin = FALSE;
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Bool  have_outline_shifted   = FALSE;
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Bool  have_buffer            = FALSE;
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* check glyph image format */
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( slot->format != render->glyph_format )
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = FT_THROW( Invalid_Argument );
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* check mode */
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( mode != required_mode )
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = FT_THROW( Cannot_Render_Glyph );
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    outline = &slot->outline;
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* translate the outline to the new origin if needed */
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( origin )
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Outline_Translate( outline, origin->x, origin->y );
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      have_translated_origin = TRUE;
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* compute the control box, and grid fit it */
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Outline_Get_CBox( outline, &cbox );
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cbox.xMax = FT_PIX_CEIL( cbox.xMax );
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cbox.yMax = FT_PIX_CEIL( cbox.yMax );
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin )
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 " xMin = %d, xMax = %d\n",
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 cbox.xMin >> 6, cbox.xMax >> 6 ));
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = FT_THROW( Raster_Overflow );
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      width = ( cbox.xMax - cbox.xMin ) >> 6;
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin )
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 " yMin = %d, yMax = %d\n",
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 cbox.yMin >> 6, cbox.yMax >> 6 ));
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = FT_THROW( Raster_Overflow );
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      height = ( cbox.yMax - cbox.yMin ) >> 6;
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    width_org  = width;
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    height_org = height;
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* release old bitmap buffer */
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FREE( bitmap->buffer );
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* allocate new one */
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pitch = width;
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( hmul )
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      width = width * 3;
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      pitch = FT_PAD_CEIL( width, 4 );
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( vmul )
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      height *= 3;
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    x_shift = (FT_Int) cbox.xMin;
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    y_shift = (FT_Int) cbox.yMin;
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    x_left  = (FT_Int)( cbox.xMin >> 6 );
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    y_top   = (FT_Int)( cbox.yMax >> 6 );
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( slot->library->lcd_filter_func )
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Int  extra = slot->library->lcd_extra;
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( hmul )
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        x_shift -= 64 * ( extra >> 1 );
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        width   += 3 * extra;
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pitch    = FT_PAD_CEIL( width, 4 );
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        x_left  -= extra >> 1;
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( vmul )
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        y_shift -= 64 * ( extra >> 1 );
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        height  += 3 * extra;
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        y_top   += extra >> 1;
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if FT_UINT_MAX > 0xFFFFU
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Required check is (pitch * height < FT_ULONG_MAX),        */
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* but we care realistic cases only.  Always pitch <= width. */
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( width > 0x7FFF || height > 0x7FFF )
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n",
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 width, height ));
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = FT_THROW( Raster_Overflow );
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bitmap->num_grays  = 256;
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bitmap->width      = width;
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bitmap->rows       = height;
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bitmap->pitch      = pitch;
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* translate outline to render it into the bitmap */
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Outline_Translate( outline, -x_shift, -y_shift );
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    have_outline_shifted = TRUE;
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      have_buffer = TRUE;
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* set up parameters */
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    params.target = bitmap;
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    params.source = outline;
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    params.flags  = FT_RASTER_FLAG_AA;
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* implode outline if needed */
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Vector*  points     = outline->points;
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Vector*  points_end = points + outline->n_points;
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Vector*  vec;
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( hmul )
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for ( vec = points; vec < points_end; vec++ )
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          vec->x *= 3;
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( vmul )
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for ( vec = points; vec < points_end; vec++ )
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          vec->y *= 3;
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* render outline into the bitmap */
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = render->raster_render( render->raster, &params );
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* deflate outline if needed */
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Vector*  points     = outline->points;
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Vector*  points_end = points + outline->n_points;
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Vector*  vec;
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( hmul )
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for ( vec = points; vec < points_end; vec++ )
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          vec->x /= 3;
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( vmul )
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for ( vec = points; vec < points_end; vec++ )
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          vec->y /= 3;
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( error )
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( slot->library->lcd_filter_func )
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      slot->library->lcd_filter_func( bitmap, mode, slot->library );
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* render outline into bitmap */
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = render->raster_render( render->raster, &params );
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( error )
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* expand it horizontally */
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( hmul )
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Byte*  line = bitmap->buffer;
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_UInt   hh;
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      for ( hh = height_org; hh > 0; hh--, line += pitch )
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FT_UInt   xx;
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FT_Byte*  end = line + width;
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for ( xx = width_org; xx > 0; xx-- )
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_UInt  pixel = line[xx-1];
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          end[-3] = (FT_Byte)pixel;
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          end[-2] = (FT_Byte)pixel;
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          end[-1] = (FT_Byte)pixel;
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          end    -= 3;
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* expand it vertically */
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( vmul )
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Byte*  read  = bitmap->buffer + ( height - height_org ) * pitch;
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Byte*  write = bitmap->buffer;
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_UInt   hh;
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      for ( hh = height_org; hh > 0; hh-- )
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ft_memcpy( write, read, pitch );
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        write += pitch;
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ft_memcpy( write, read, pitch );
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        write += pitch;
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ft_memcpy( write, read, pitch );
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        write += pitch;
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        read  += pitch;
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /*
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     * XXX: on 16bit system, we return an error for huge bitmap
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     * to prevent an overflow.
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     */
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX )
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = FT_THROW( Invalid_Pixel_Size );
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    slot->format      = FT_GLYPH_FORMAT_BITMAP;
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    slot->bitmap_left = (FT_Int)x_left;
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    slot->bitmap_top  = (FT_Int)y_top;
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* everything is fine; don't deallocate buffer */
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    have_buffer = FALSE;
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = FT_Err_Ok;
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Exit:
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( have_outline_shifted )
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Outline_Translate( outline, x_shift, y_shift );
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( have_translated_origin )
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Outline_Translate( outline, -origin->x, -origin->y );
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( have_buffer )
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FREE( bitmap->buffer );
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* convert a slot's glyph image into a bitmap */
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ft_smooth_render( FT_Renderer       render,
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FT_GlyphSlot      slot,
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FT_Render_Mode    mode,
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    const FT_Vector*  origin )
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( mode == FT_RENDER_MODE_LIGHT )
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      mode = FT_RENDER_MODE_NORMAL;
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ft_smooth_render_generic( render, slot, mode, origin,
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     FT_RENDER_MODE_NORMAL );
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* convert a slot's glyph image into a horizontal LCD bitmap */
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ft_smooth_render_lcd( FT_Renderer       render,
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FT_GlyphSlot      slot,
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FT_Render_Mode    mode,
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        const FT_Vector*  origin )
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error  error;
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = ft_smooth_render_generic( render, slot, mode, origin,
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      FT_RENDER_MODE_LCD );
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !error )
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD;
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* convert a slot's glyph image into a vertical LCD bitmap */
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ft_smooth_render_lcd_v( FT_Renderer       render,
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          FT_GlyphSlot      slot,
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          FT_Render_Mode    mode,
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          const FT_Vector*  origin )
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error  error;
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = ft_smooth_render_generic( render, slot, mode, origin,
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      FT_RENDER_MODE_LCD_V );
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !error )
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V;
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_RENDERER( ft_smooth_renderer_class,
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_MODULE_RENDERER,
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      sizeof ( FT_RendererRec ),
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      "smooth",
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0x10000L,
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0x20000L,
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0,    /* module specific interface */
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      (FT_Module_Constructor)ft_smooth_init,
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      (FT_Module_Destructor) 0,
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      (FT_Module_Requester)  0
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ,
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_GLYPH_FORMAT_OUTLINE,
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_RenderFunc)   ft_smooth_render,
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_TransformFunc)ft_smooth_transform,
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_RENDERER( ft_smooth_lcd_renderer_class,
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_MODULE_RENDERER,
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      sizeof ( FT_RendererRec ),
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      "smooth-lcd",
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0x10000L,
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0x20000L,
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0,    /* module specific interface */
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      (FT_Module_Constructor)ft_smooth_init,
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      (FT_Module_Destructor) 0,
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      (FT_Module_Requester)  0
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ,
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_GLYPH_FORMAT_OUTLINE,
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_RenderFunc)   ft_smooth_render_lcd,
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_TransformFunc)ft_smooth_transform,
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_RENDERER( ft_smooth_lcdv_renderer_class,
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_MODULE_RENDERER,
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      sizeof ( FT_RendererRec ),
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      "smooth-lcdv",
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0x10000L,
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0x20000L,
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0,    /* module specific interface */
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      (FT_Module_Constructor)ft_smooth_init,
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      (FT_Module_Destructor) 0,
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      (FT_Module_Requester)  0
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ,
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_GLYPH_FORMAT_OUTLINE,
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_RenderFunc)   ft_smooth_render_lcd_v,
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_TransformFunc)ft_smooth_transform,
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */
535