source: trunk/poppler/freetype2/src/smooth/ftsmooth.c @ 262

Last change on this file since 262 was 262, checked in by Eugene Romanenko, 12 years ago

PDF plugin: freetype library updated to version 2.3.8

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