ReactOS 0.4.16-dev-2332-g4cba65d
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
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
131 {
133 FT_Vector* sub = render->root.library->lcd_geometry;
134 FT_Pos x, y;
135
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;
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
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;
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
274 {
276 FT_Vector* points = outline->points;
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;
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
306 {
308 FT_Vector* points = outline->points;
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;
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
371 {
373 FT_Vector* points = outline->points;
374 FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
375 FT_Vector* vec;
376
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
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 {
500 if ( outline->flags & FT_OUTLINE_OVERLAP )
502 else
503 {
505
506
507 params.target = bitmap;
508 params.source = outline;
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
584 FT_GLYPH_FORMAT_OUTLINE,
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 NULL
Definition: types.h:112
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
FT_Vector * vec
Definition: ftbbox.c:469
return FT_Err_Ok
Definition: ftbbox.c:526
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_RASTER_FLAG_AA
Definition: ftimage.h:967
@ FT_PIXEL_MODE_LCD_V
Definition: ftimage.h:188
#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_LCD_FILTER_DEFAULT
Definition: ftlcdfil.h:163
FT_Library_SetLcdFilter(FT_Library library, FT_LcdFilter filter)
Definition: ftlcdfil.c:407
#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
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_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_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
#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
struct TOrigin_ TOrigin
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
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:64
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
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint GLenum matrix
Definition: glext.h:9407
GLenum mode
Definition: glext.h:6217
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLenum dst
Definition: glext.h:6340
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLsizei const GLfloat * points
Definition: glext.h:8112
voidpf uLong int origin
Definition: ioapi.h:144
#define error(str)
Definition: mkdosfs.c:1605
#define for
Definition: utility.h:88
static char memory[1024 *256]
Definition: process.c:122
static int sum(int x_, int y_)
Definition: ptr2_test.cpp:35
static void Exit(void)
Definition: sock.c:1330
static void render(void)
Definition: ssstars.c:272
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
Definition: vfat.h:185
Definition: uimain.c:89
uint32 width
Definition: uimain.c:91
Definition: mesh.c:5330
Definition: tools.h:99