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