w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ftsmooth.c
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * ftsmooth.c
4  *
5  * Anti-aliasing renderer interface (body).
6  *
7  * Copyright (C) 2000-2020 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 <freetype/internal/ftdebug.h>
20 #include <freetype/internal/ftobjs.h>
21 #include <freetype/ftoutln.h>
22 #include "ftsmooth.h"
23 #include "ftgrays.h"
24 
25 #include "ftsmerrs.h"
26 
27 
28  /* sets render-specific mode */
29  static FT_Error
31  FT_ULong mode_tag,
33  {
34  /* we simply pass it to the raster */
35  return render->clazz->raster_class->raster_set_mode( render->raster,
36  mode_tag,
37  data );
38  }
39 
40  /* transform a given glyph image */
41  static FT_Error
44  const FT_Matrix* matrix,
45  const FT_Vector* delta )
46  {
48 
49 
50  if ( slot->format != render->glyph_format )
51  {
52  error = FT_THROW( Invalid_Argument );
53  goto Exit;
54  }
55 
56  if ( matrix )
57  FT_Outline_Transform( &slot->outline, matrix );
58 
59  if ( delta )
60  FT_Outline_Translate( &slot->outline, delta->x, delta->y );
61 
62  Exit:
63  return error;
64  }
65 
66 
67  /* return the glyph's control box */
68  static void
71  FT_BBox* cbox )
72  {
73  FT_ZERO( cbox );
74 
75  if ( slot->format == render->glyph_format )
76  FT_Outline_Get_CBox( &slot->outline, cbox );
77  }
78 
79  typedef struct TOrigin_
80  {
81  unsigned char* origin; /* pixmap origin at the bottom-left */
82  int pitch; /* pitch to go down one row */
83 
85 
86 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
87 
88  /* initialize renderer -- init its raster */
89  static FT_Error
91  {
92  FT_Vector* sub = render->root.library->lcd_geometry;
93 
94 
95  /* set up default subpixel geometry for striped RGB panels. */
96  sub[0].x = -21;
97  sub[0].y = 0;
98  sub[1].x = 0;
99  sub[1].y = 0;
100  sub[2].x = 21;
101  sub[2].y = 0;
102 
103  render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
104 
105  return 0;
106  }
107 
108 
109  /* This function writes every third byte in direct rendering mode */
110  static void
112  int count,
113  const FT_Span* spans,
114  TOrigin* target )
115  {
116  unsigned char* dst_line = target->origin - y * target->pitch;
117  unsigned char* dst;
118  unsigned short w;
119 
120 
121  for ( ; count--; spans++ )
122  for ( dst = dst_line + spans->x * 3, w = spans->len; w--; dst += 3 )
123  *dst = spans->coverage;
124  }
125 
126 
127  static FT_Error
130  FT_Bitmap* bitmap )
131  {
133  FT_Vector* sub = render->root.library->lcd_geometry;
134  FT_Pos x, y;
135 
137  TOrigin target;
138 
139 
140  /* Render 3 separate coverage bitmaps, shifting the outline. */
141  /* Set up direct rendering to record them on each third byte. */
142  params.source = outline;
144  params.gray_spans = (FT_SpanFunc)ft_smooth_lcd_spans;
145  params.user = &target;
146 
147  params.clip_box.xMin = 0;
148  params.clip_box.yMin = 0;
149  params.clip_box.xMax = bitmap->width;
150  params.clip_box.yMax = bitmap->rows;
151 
152  if ( bitmap->pitch < 0 )
153  target.origin = bitmap->buffer;
154  else
155  target.origin = bitmap->buffer
156  + ( bitmap->rows - 1 ) * (unsigned int)bitmap->pitch;
157 
158  target.pitch = bitmap->pitch;
159 
161  -sub[0].x,
162  -sub[0].y );
163  error = render->raster_render( render->raster, &params );
164  x = sub[0].x;
165  y = sub[0].y;
166  if ( error )
167  goto Exit;
168 
169  target.origin++;
171  sub[0].x - sub[1].x,
172  sub[0].y - sub[1].y );
173  error = render->raster_render( render->raster, &params );
174  x = sub[1].x;
175  y = sub[1].y;
176  if ( error )
177  goto Exit;
178 
179  target.origin++;
181  sub[1].x - sub[2].x,
182  sub[1].y - sub[2].y );
183  error = render->raster_render( render->raster, &params );
184  x = sub[2].x;
185  y = sub[2].y;
186 
187  Exit:
189 
190  return error;
191  }
192 
193 
194  static FT_Error
197  FT_Bitmap* bitmap )
198  {
200  int pitch = bitmap->pitch;
201  FT_Vector* sub = render->root.library->lcd_geometry;
202  FT_Pos x, y;
203 
205 
206 
207  params.target = bitmap;
208  params.source = outline;
209  params.flags = FT_RASTER_FLAG_AA;
210 
211  /* Render 3 separate coverage bitmaps, shifting the outline. */
212  /* Notice that the subpixel geometry vectors are rotated. */
213  /* Triple the pitch to render on each third row. */
214  bitmap->pitch *= 3;
215  bitmap->rows /= 3;
216 
218  -sub[0].y,
219  sub[0].x );
220  error = render->raster_render( render->raster, &params );
221  x = sub[0].y;
222  y = -sub[0].x;
223  if ( error )
224  goto Exit;
225 
226  bitmap->buffer += pitch;
228  sub[0].y - sub[1].y,
229  sub[1].x - sub[0].x );
230  error = render->raster_render( render->raster, &params );
231  x = sub[1].y;
232  y = -sub[1].x;
233  bitmap->buffer -= pitch;
234  if ( error )
235  goto Exit;
236 
237  bitmap->buffer += 2 * pitch;
239  sub[1].y - sub[2].y,
240  sub[2].x - sub[1].x );
241  error = render->raster_render( render->raster, &params );
242  x = sub[2].y;
243  y = -sub[2].x;
244  bitmap->buffer -= 2 * pitch;
245 
246  Exit:
248 
249  bitmap->pitch /= 3;
250  bitmap->rows *= 3;
251 
252  return error;
253  }
254 
255 #else /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
256 
257  /* initialize renderer -- init its raster */
258  static FT_Error
260  {
261  /* set up default LCD filtering */
263 
264  render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
265 
266  return 0;
267  }
268 
269 
270  static FT_Error
273  FT_Bitmap* bitmap )
274  {
277  FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
278  FT_Vector* vec;
279 
281 
282 
283  params.target = bitmap;
284  params.source = outline;
285  params.flags = FT_RASTER_FLAG_AA;
286 
287  /* implode outline */
288  for ( vec = points; vec < points_end; vec++ )
289  vec->x *= 3;
290 
291  /* render outline into the bitmap */
292  error = render->raster_render( render->raster, &params );
293 
294  /* deflate outline */
295  for ( vec = points; vec < points_end; vec++ )
296  vec->x /= 3;
297 
298  return error;
299  }
300 
301 
302  static FT_Error
305  FT_Bitmap* bitmap )
306  {
309  FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
310  FT_Vector* vec;
311 
313 
314 
315  params.target = bitmap;
316  params.source = outline;
317  params.flags = FT_RASTER_FLAG_AA;
318 
319  /* implode outline */
320  for ( vec = points; vec < points_end; vec++ )
321  vec->y *= 3;
322 
323  /* render outline into the bitmap */
324  error = render->raster_render( render->raster, &params );
325 
326  /* deflate outline */
327  for ( vec = points; vec < points_end; vec++ )
328  vec->y /= 3;
329 
330  return error;
331  }
332 
333 #endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
334 
335 /* Oversampling scale to be used in rendering overlaps */
336 #define SCALE ( 1 << 2 )
337 
338  /* This function averages inflated spans in direct rendering mode */
339  static void
341  int count,
342  const FT_Span* spans,
343  TOrigin* target )
344  {
345  unsigned char* dst = target->origin - ( y / SCALE ) * target->pitch;
346  unsigned short x;
347  unsigned int cover, sum;
348 
349 
350  /* When accumulating the oversampled spans we need to assure that */
351  /* fully covered pixels are equal to 255 and do not overflow. */
352  /* It is important that the SCALE is a power of 2, each subpixel */
353  /* cover can also reach a power of 2 after rounding, and the total */
354  /* is clamped to 255 when it adds up to 256. */
355  for ( ; count--; spans++ )
356  {
357  cover = ( spans->coverage + SCALE * SCALE / 2 ) / ( SCALE * SCALE );
358  for ( x = 0; x < spans->len; x++ )
359  {
360  sum = dst[( spans->x + x ) / SCALE] + cover;
361  dst[( spans->x + x ) / SCALE] = (unsigned char)( sum - ( sum >> 8 ) );
362  }
363  }
364  }
365 
366 
367  static FT_Error
370  FT_Bitmap* bitmap )
371  {
374  FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
375  FT_Vector* vec;
376 
378  TOrigin target;
379 
380 
381  /* Reject outlines that are too wide for 16-bit FT_Span. */
382  /* Other limits are applied upstream with the same error code. */
383  if ( bitmap->width * SCALE > 0x7FFF )
384  return FT_THROW( Raster_Overflow );
385 
386  /* Set up direct rendering to average oversampled spans. */
387  params.source = outline;
390  params.user = &target;
391 
392  params.clip_box.xMin = 0;
393  params.clip_box.yMin = 0;
394  params.clip_box.xMax = bitmap->width * SCALE;
395  params.clip_box.yMax = bitmap->rows * SCALE;
396 
397  if ( bitmap->pitch < 0 )
398  target.origin = bitmap->buffer;
399  else
400  target.origin = bitmap->buffer
401  + ( bitmap->rows - 1 ) * (unsigned int)bitmap->pitch;
402 
403  target.pitch = bitmap->pitch;
404 
405  /* inflate outline */
406  for ( vec = points; vec < points_end; vec++ )
407  {
408  vec->x *= SCALE;
409  vec->y *= SCALE;
410  }
411 
412  /* render outline into the bitmap */
413  error = render->raster_render( render->raster, &params );
414 
415  /* deflate outline */
416  for ( vec = points; vec < points_end; vec++ )
417  {
418  vec->x /= SCALE;
419  vec->y /= SCALE;
420  }
421 
422  return error;
423  }
424 
425 #undef SCALE
426 
427  static FT_Error
431  const FT_Vector* origin )
432  {
434  FT_Outline* outline = &slot->outline;
435  FT_Bitmap* bitmap = &slot->bitmap;
436  FT_Memory memory = render->root.memory;
437  FT_Pos x_shift = 0;
438  FT_Pos y_shift = 0;
439 
440 
441  /* check glyph image format */
442  if ( slot->format != render->glyph_format )
443  {
444  error = FT_THROW( Invalid_Argument );
445  goto Exit;
446  }
447 
448  /* check mode */
449  if ( mode != FT_RENDER_MODE_NORMAL &&
453  {
454  error = FT_THROW( Cannot_Render_Glyph );
455  goto Exit;
456  }
457 
458  /* release old bitmap buffer */
459  if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
460  {
461  FT_FREE( bitmap->buffer );
462  slot->internal->flags &= ~~FT_GLYPH_OWN_BITMAP;
463  }
464 
465  if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) )
466  {
467  error = FT_THROW( Raster_Overflow );
468  goto Exit;
469  }
470 
471  if ( !bitmap->rows || !bitmap->pitch )
472  goto Exit;
473 
474  /* allocate new one */
475  if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
476  goto Exit;
477 
478  slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
479 
480  x_shift = 64 * -slot->bitmap_left;
481  y_shift = 64 * -slot->bitmap_top;
482  if ( bitmap->pixel_mode == FT_PIXEL_MODE_LCD_V )
483  y_shift += 64 * (FT_Int)bitmap->rows / 3;
484  else
485  y_shift += 64 * (FT_Int)bitmap->rows;
486 
487  if ( origin )
488  {
489  x_shift += origin->x;
490  y_shift += origin->y;
491  }
492 
493  /* translate outline to render it into the bitmap */
494  if ( x_shift || y_shift )
495  FT_Outline_Translate( outline, x_shift, y_shift );
496 
497  if ( mode == FT_RENDER_MODE_NORMAL ||
499  {
502  else
503  {
505 
506 
507  params.target = bitmap;
508  params.source = outline;
509  params.flags = FT_RASTER_FLAG_AA;
510 
511  error = render->raster_render( render->raster, &params );
512  }
513  }
514  else
515  {
516  if ( mode == FT_RENDER_MODE_LCD )
518  else if ( mode == FT_RENDER_MODE_LCD_V )
520 
521 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
522 
523  /* finally apply filtering */
524  {
525  FT_Byte* lcd_weights;
526  FT_Bitmap_LcdFilterFunc lcd_filter_func;
527 
528 
529  /* Per-face LCD filtering takes priority if set up. */
530  if ( slot->face && slot->face->internal->lcd_filter_func )
531  {
532  lcd_weights = slot->face->internal->lcd_weights;
533  lcd_filter_func = slot->face->internal->lcd_filter_func;
534  }
535  else
536  {
537  lcd_weights = slot->library->lcd_weights;
538  lcd_filter_func = slot->library->lcd_filter_func;
539  }
540 
541  if ( lcd_filter_func )
542  lcd_filter_func( bitmap, lcd_weights );
543  }
544 
545 #endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
546 
547  }
548 
549  Exit:
550  if ( !error )
551  {
552  /* everything is fine; the glyph is now officially a bitmap */
553  slot->format = FT_GLYPH_FORMAT_BITMAP;
554  }
555  else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
556  {
557  FT_FREE( bitmap->buffer );
558  slot->internal->flags &= ~~FT_GLYPH_OWN_BITMAP;
559  }
560 
561  if ( x_shift || y_shift )
562  FT_Outline_Translate( outline, -x_shift, -y_shift );
563 
564  return error;
565  }
566 
567 
569  ft_smooth_renderer_class,
570 
572  sizeof ( FT_RendererRec ),
573 
574  "smooth",
575  0x10000L,
576  0x20000L,
577 
578  NULL, /* module specific interface */
579 
580  (FT_Module_Constructor)ft_smooth_init, /* module_init */
581  (FT_Module_Destructor) NULL, /* module_done */
582  (FT_Module_Requester) NULL, /* get_interface */
583 
585 
586  (FT_Renderer_RenderFunc) ft_smooth_render, /* render_glyph */
587  (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */
588  (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */
590 
591  (FT_Raster_Funcs*)&ft_grays_raster /* raster_class */
592  )
593 
594 
595 /* END */
#define count(a)
Definition: aptex-macros.h:781
#define mode
Definition: aptex-macros.h:510
#define FT_LCD_FILTER_DEFAULT
Definition: cairo-ft-font.c:91
int params
Definition: definitions.c:42
int w
Definition: dviconv.c:26
#define error(a)
Definition: dviinfo.c:48
struct rect data
Definition: dvipdfm.c:64
void Exit(int code)
Definition: dvispc.c:374
enum FT_Render_Mode_ FT_Render_Mode
@ FT_RENDER_MODE_NORMAL
Definition: freetype.h:3249
@ FT_RENDER_MODE_LIGHT
Definition: freetype.h:3250
@ FT_RENDER_MODE_LCD_V
Definition: freetype.h:3253
@ FT_RENDER_MODE_LCD
Definition: freetype.h:3252
#define FT_RASTER_FLAG_AA
Definition: ftimage.h:967
@ FT_PIXEL_MODE_LCD_V
Definition: ftimage.h:188
@ FT_GLYPH_FORMAT_OUTLINE
Definition: ftimage.h:749
@ FT_GLYPH_FORMAT_BITMAP
Definition: ftimage.h:748
#define FT_RASTER_FLAG_DIRECT
Definition: ftimage.h:968
#define FT_OUTLINE_OVERLAP
Definition: ftimage.h:441
void(* FT_SpanFunc)(int y, int count, const FT_Span *spans, void *user)
Definition: ftimage.h:898
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:57
FT_Library_SetLcdFilter(FT_Library library, FT_LcdFilter filter)
Definition: ftlcdfil.c:407
void(* FT_Module_Destructor)(FT_Module module)
Definition: ftmodapi.h:168
#define FT_MODULE_RENDERER
Definition: ftmodapi.h:110
FT_Error(* FT_Module_Constructor)(FT_Module module)
Definition: ftmodapi.h:152
FT_Module_Interface(* FT_Module_Requester)(FT_Module module, const char *name)
Definition: ftmodapi.h:187
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:507
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:706
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:457
FT_Error(* FT_Renderer_SetModeFunc)(FT_Renderer renderer, FT_ULong mode_tag, FT_Pointer mode_ptr)
Definition: ftrender.h:107
FT_Error(* FT_Renderer_TransformFunc)(FT_Renderer renderer, FT_GlyphSlot slot, const FT_Matrix *matrix, const FT_Vector *delta)
Definition: ftrender.h:94
void(* FT_Renderer_GetCBoxFunc)(FT_Renderer renderer, FT_GlyphSlot slot, FT_BBox *cbox)
Definition: ftrender.h:101
FT_Error(* FT_Renderer_RenderFunc)(FT_Renderer renderer, FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector *origin)
Definition: ftrender.h:88
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:64
void * FT_Pointer
Definition: fttypes.h:310
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
int FT_Error
Definition: fttypes.h:299
signed int FT_Int
Definition: fttypes.h:220
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_ALLOC_MULT(ptr, count, item_size)
Definition: ftmemory.h:317
#define FT_FREE(ptr)
Definition: ftmemory.h:337
#define FT_OFFSET(base, count)
Definition: ftmemory.h:66
#define FT_ZERO(p)
Definition: ftmemory.h:246
#define NULL
Definition: ftobjs.h:61
FT_Bool ft_glyphslot_preset_bitmap(FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector *origin)
Definition: ftobjs.c:347
#define FT_GLYPH_OWN_BITMAP
Definition: ftobjs.h:421
#define FT_DEFINE_RENDERER( class_, flags_, size_, name_, version_, requires_, interface_, init_, done_, get_interface_, glyph_format_, render_glyph_, transform_glyph_, get_glyph_cbox_, set_mode_, raster_class_)
Definition: ftobjs.h:1108
FT_Vector * vec
Definition: ftbbox.c:469
return FT_Err_Ok
Definition: ftbbox.c:526
for(n=0;n< outline->n_points;n++)
Definition: ftbbox.c:494
const FT_Raster_Funcs ft_grays_raster
struct TOrigin_ TOrigin
kerning y
Definition: ttdriver.c:212
int int double double double char double points
Definition: gdfx.h:18
#define cover(idx)
Definition: JPXStream.cc:177
@ render
Definition: spc_dvips.c:728
F2Dot14 SCALE
Definition: tables.h:211
#define target(code, i)
Definition: lpeg.c:1165
float x
Definition: cordic.py:15
char * bitmap
Definition: pbmpage.c:35
static int delta
Definition: pbmtolj.c:36
float ** matrix()
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF base if bpp PF set rept prefetch_distance PF set OFFSET endr endif endm macro preload_leading_step2 base if bpp ifc DST PF PF else if bpp lsl PF PF lsl PF sub
#define SCALE
Definition: ftsmooth.c:336
static FT_Error ft_smooth_raster_lcdv(FT_Renderer render, FT_Outline *outline, FT_Bitmap *bitmap)
Definition: ftsmooth.c:195
static void ft_smooth_lcd_spans(int y, int count, const FT_Span *spans, TOrigin *target)
Definition: ftsmooth.c:111
static FT_Error ft_smooth_init(FT_Renderer render)
Definition: ftsmooth.c:90
static FT_Error ft_smooth_set_mode(FT_Renderer render, FT_ULong mode_tag, FT_Pointer data)
Definition: ftsmooth.c:30
static void ft_smooth_overlap_spans(int y, int count, const FT_Span *spans, TOrigin *target)
Definition: ftsmooth.c:340
static FT_Error ft_smooth_raster_overlap(FT_Renderer render, FT_Outline *outline, FT_Bitmap *bitmap)
Definition: ftsmooth.c:368
static void ft_smooth_get_cbox(FT_Renderer render, FT_GlyphSlot slot, FT_BBox *cbox)
Definition: ftsmooth.c:69
static FT_Error ft_smooth_transform(FT_Renderer render, FT_GlyphSlot slot, const FT_Matrix *matrix, const FT_Vector *delta)
Definition: ftsmooth.c:42
static FT_Error ft_smooth_render(FT_Renderer render, FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector *origin)
Definition: ftsmooth.c:428
static FT_Error ft_smooth_raster_lcd(FT_Renderer render, FT_Outline *outline, FT_Bitmap *bitmap)
Definition: ftsmooth.c:128
slotref slot
Definition: opcodes.h:237
unsigned char coverage
Definition: ftimage.h:862
short x
Definition: ftimage.h:860
unsigned short len
Definition: ftimage.h:861
FT_Pos x
Definition: ftimage.h:77
FT_Pos y
Definition: ftimage.h:78
int pitch
Definition: ftsmooth.c:82
unsigned char * origin
Definition: ftsmooth.c:81
TT_Byte * flags
Definition: freetype.h:179
TT_UShort n_points
Definition: freetype.h:176
TT_Vector * points
Definition: freetype.h:178
Definition: gf2pbm.c:137
TT_Outline outline
Definition: ttf2pfb.c:167