1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* State and interface definitions for a spot analyzer device. */
18 
19 /*
20  * A spot analyzer device performs an analyzis while handling an output
21  * of the trapezoid fill algorithm for 2 purposes :
22  * a glyph grid fitting, and
23  * a glyph antialiased rendering any number of alpha bits.
24  * Currently we only implement a vertical stem recognition for the grid fitting.
25  */
26 
27 #ifndef gzspotan_INCLUDED
28 #  define gzspotan_INCLUDED
29 
30 #include "gxdevcli.h"
31 #include "gzpath.h"
32 
33 /* -------------- Structures ----------------------------- */
34 
35 typedef struct gx_san_trap_s gx_san_trap;
36 typedef struct gx_san_trap_contact_s gx_san_trap_contact;
37 
38 /* A trapezoid. */
39 struct gx_san_trap_s {
40     /* Buffer link : */
41     gx_san_trap *link; /* Buffer link. */
42     /* The geometry : */
43     fixed ybot, ytop;
44     fixed xlbot, xrbot, xltop, xrtop;
45     /* The spot topology representation : */
46     gx_san_trap_contact *upper; /* Neighbours of the upper band. */
47     const segment *l; /* Outline pointer : left boundary. */
48     const segment *r; /* Outline pointer : right boundary. */
49     int dir_l, dir_r; /* Outline direction : left, right. */
50     bool leftmost, rightmost;
51     /* The topology reconstrustor work data : */
52     gx_san_trap *next; /* Next with same ytop. */
53     gx_san_trap *prev; /* Prev with same ytop. */
54     /* The stem recognizer work data : */
55     bool visited;
56     int fork;
57 };
58 #define private_st_san_trap() /* When GC is invoked, only the buffer link is valid. */\
59   gs_private_st_ptrs1(st_san_trap, gx_san_trap, "gx_san_trap", \
60     san_trap_enum_ptrs, san_trap_reloc_ptrs, link)
61 
62 /* A contact of 2 trapezoids. */
63 /* Represents a neighbourship through a band boundary. */
64 struct gx_san_trap_contact_s {
65     /* Buffer link : */
66     gx_san_trap_contact *link; /* Buffer link. */
67     gx_san_trap_contact *next; /* Next element of the same relation, a cyclic list. */
68     gx_san_trap_contact *prev; /* Prev element of the same relation, a cyclic list. */
69     gx_san_trap *upper, *lower; /* A contacting pair. */
70 };
71 #define private_st_san_trap_contact() /* When GC is invoked, only the buffer link is valid. */\
72   gs_private_st_ptrs1(st_san_trap_contact, gx_san_trap_contact, "gx_san_trap_contact",\
73   san_trap_contact_enum_ptrs, san_trap_contact_reloc_ptrs, link)
74 
75 /* A stem section. */
76 typedef struct gx_san_sect_s gx_san_sect;
77 struct gx_san_sect_s {
78     fixed xl, yl, xr, yr;
79     const segment *l, *r;
80     int side_mask;
81 };
82 
83 /* A spot analyzer device. */
84 struct gx_device_spot_analyzer_s {
85     gx_device_common;
86     int lock;
87     /* Buffers : */
88     gx_san_trap *trap_buffer, *trap_buffer_last, *trap_free;
89     gx_san_trap_contact *cont_buffer, *cont_buffer_last, *cont_free;
90     int trap_buffer_count;
91     int cont_buffer_count;
92     /* The topology reconstrustor work data (no GC invocations) : */
93     gx_san_trap *bot_band;
94     gx_san_trap *top_band;
95     gx_san_trap *bot_current;
96     /* The stem recognizer work data (no GC invocations) : */
97     fixed xmin, xmax;
98 };
99 
100 extern_st(st_device_spot_analyzer);
101 #define public_st_device_spot_analyzer() /* When GC is invoked, only the buffer links are valid. */\
102     gs_public_st_suffix_add4_final(st_device_spot_analyzer, gx_device_spot_analyzer,\
103             "gx_device_spot_analyzer", device_spot_analyzer_enum_ptrs,\
104             device_spot_analyzer_reloc_ptrs, gx_device_finalize, st_device,\
105             trap_buffer, trap_buffer_last, cont_buffer, cont_buffer_last)
106 
107 /* -------------- Interface methods ----------------------------- */
108 
109 /* Obtain a spot analyzer device. */
110 int gx_san__obtain(gs_memory_t *mem, gx_device_spot_analyzer **ppadev);
111 
112 /* Obtain a spot analyzer device. */
113 void gx_san__release(gx_device_spot_analyzer **ppadev);
114 
115 /* Start accumulating a path. */
116 void gx_san_begin(gx_device_spot_analyzer *padev);
117 
118 /* Store a tarpezoid. */
119 /* Assumes an Y-band scanning order with increasing X inside a band. */
120 int gx_san_trap_store(gx_device_spot_analyzer *padev,
121     fixed ybot, fixed ytop, fixed xlbot, fixed xrbot, fixed xltop, fixed xrtop,
122     const segment *l, const segment *r, int dir_l, int dir_r);
123 
124 /* Finish accumulating a path. */
125 void gx_san_end(const gx_device_spot_analyzer *padev);
126 
127 /* Generate stems. */
128 int gx_san_generate_stems(gx_device_spot_analyzer *padev,
129                 bool overall_hints, void *client_data,
130                 int (*handler)(void *client_data, gx_san_sect *ss));
131 
132 /* -------------- Other external symbols ------------------------ */
133 
134 /* is_spotan_device() in gxfill.c uses san_open */
135 /* to identify the spot analyzer device         */
136 dev_proc_open_device(san_open);
137 
138 #endif /* gzspotan_INCLUDED */
139