xref: /plan9/sys/src/cmd/gs/src/gxfdrop.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 2003 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gxfdrop.h,v 1.4 2003/11/25 08:34:07 igor Exp $ */
18 /* Dropout prevention for a character rasterization. */
19 
20 #ifndef gxfdrop_INCLUDED
21 #  define gxfdrop_INCLUDED
22 
23 
24 /*  The structure margin_set and related structures and functions are used for
25     preventing dropouts rasterizing a character with zero fill adjustment. The purpose
26     is to paint something along thin quazi-horizontal stems,
27     which are composed of multiple small segments (such as a result of flattenpath).
28     We call it "pseudo-rasterization".
29     When fill adjustment takes place, this stuff is not required and is being skipped.
30 
31     To prevent dropouts in thin quazi-horizontal stems we look at raster
32     through 1xN pixels window, where N is the width of the path bounding box.
33     This window moves from bottom to top synchronousely with the motion of
34     the filling loop, but its Y coordinate is always an integer plus one half
35     (actually it moves convulsively).
36     Through this window we can see an upper half of a pixel row,
37     and lower half of the next pixel row. Painted spots are visible through
38     this window as a set of "margins". To handle them we maintain
39     a list of margin_s structures (each of which describes an interval
40     to be painted), and array of "sections" (i-th section corresponds to
41     half-integer X-coordinate Xi = bbox_left + i + 0.5, and stores fraction
42     part of y-coordinate of intersection of the line x == Xi with margin
43     boudaries, being visible through window (only extremal coordinates are stored
44     into a section)).
45 
46     The structure margin_set snaps what has been painted inside window.
47     We handle 2 instances of margin_set : margin_set0 is being prepared and margin_set1 is
48     being refinished. When the filling loop steps down over a pixel center,
49     the refinished window is closed and released, the prapared window becomes
50     the refinished one, and a new one starts to prepare.
51 
52     fixme:
53     The current implementation is not optimised for very bold characters.
54     We could encrease performance for them with maintaining
55     a separate list of "exclusive" margins, which correspond
56     to intervals painted with regular trapezoids and made with
57     complete_margin. Using them we could skip access to 'sect' array elements
58     inside "exclusive" margins, so that the number of small steps
59     sensibly decreeses.
60 
61     fixme:
62     Another optimization could be applied to the regular(old) trapezoid algorithm.
63     Currently it breaks stems at any step of the Y cycle,
64     generating big number of trapezoids.
65     Perhaps we could store trapezoid vertices to active_line,
66     and delay rendering a trapezoid until stem changes boundary segments.
67     This also would make calls to the margin staff less frequent.
68 
69 */
70 
71 /*
72  * Configuration flags for the dropout prevention code.
73  */
74 #define ADJUST_SERIF 1 /* See comments near occurances. */
75 #define CHECK_SPOT_CONTIGUITY 1 /* See comments near occurances. */
76 
77 #ifndef active_line_DEFINED
78 #  define active_line_DEFINED
79 typedef struct active_line_s active_line;
80 #endif
81 
82 #ifndef line_list_DEFINED
83 #  define line_list_DEFINED
84 typedef struct line_list_s line_list;
85 #endif
86 
87 typedef struct margin_s
88 {   int ibeg, iend; /* Pixel indices of an interval to paint. */
89     struct margin_s *prev, *next;
90 } margin;
91 
92 typedef struct section_s
93 {   short y0, y1; /* Fraction part of y coordinates of intersections of the margin with line x==i + bbox_left */
94 #if ADJUST_SERIF && CHECK_SPOT_CONTIGUITY
95     short x0, x1; /* Pixel coverage by X for checking the contiguity. */
96 #endif
97 } section;
98 
99 typedef struct margin_set_s
100 {   fixed y;
101     margin *margin_list, *margin_touched;
102     section *sect;
103 } margin_set;
104 
105 extern_st(st_section);
106 
107 /* vd_trace helpers. */
108 #define VD_SCALE 0.03
109 #define VD_RECT(x, y, w, h, c) vd_rect(int2fixed(x), int2fixed(y), int2fixed(x + w), int2fixed(y + h), 1, c)
110 #define VD_TRAP_COLOR RGB(0, 255, 255)
111 #define VD_MARG_COLOR RGB(255, 0, 0)
112 
113 void init_section(section *sect, int i0, int i1);
114 void free_all_margins(line_list * ll);
115 int close_margins(gx_device * dev, line_list * ll, margin_set *ms);
116 int process_h_lists(line_list * ll, active_line * plp, active_line * flp, active_line * alp, fixed y0, fixed y1);
117 int margin_interior(line_list * ll, active_line * flp, active_line * alp, fixed y0, fixed y1);
118 int start_margin_set(gx_device * dev, line_list * ll, fixed y0);
119 int continue_margin_common(line_list * ll, margin_set * set, active_line * flp, active_line * alp, fixed y0, fixed y1);
120 
121 #endif /* gxfdrop_INCLUDED */
122