xref: /plan9/sys/src/cmd/gs/src/gxtext.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1998, 2000 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: gxtext.h,v 1.16 2004/12/22 18:52:23 igor Exp $ */
18 /* Driver text interface implementation support */
19 
20 #ifndef gxtext_INCLUDED
21 #  define gxtext_INCLUDED
22 
23 #include "gstext.h"
24 #include "gsrefct.h"
25 
26 /* Define the abstract type for the object procedures. */
27 typedef struct gs_text_enum_procs_s gs_text_enum_procs_t;
28 
29 #ifndef cached_fm_pair_DEFINED
30 #  define cached_fm_pair_DEFINED
31 typedef struct cached_fm_pair_s cached_fm_pair;
32 #endif
33 
34 /*
35  * Define values returned by text_process to the client.
36  */
37 typedef struct gs_text_returned_s {
38     gs_char current_char;	/* INTERVENE */
39     gs_glyph current_glyph;	/* INTERVENE */
40     gs_point total_width;	/* RETURN_WIDTH */
41 } gs_text_returned_t;
42 
43 /*
44  * Define the stack for composite fonts.
45  * If the current font is not composite, depth = -1.
46  * If the current font is composite, 0 <= depth <= MAX_FONT_STACK.
47  * items[0] through items[depth] are occupied.
48  * items[0].font is the root font; items[0].index = 0.
49  * The root font must be composite, but may be of any map type.
50  * items[0..N-1] are modal composite fonts, for some N <= depth.
51  * items[N..depth-1] are non-modal composite fonts.
52  * items[depth] is a base (non-composite) font.
53  * Note that if depth >= 0, the font member of the graphics state
54  * for a base font BuildChar/Glyph is the same as items[depth].font.
55  */
56 #define MAX_FONT_STACK 5
57 typedef struct gx_font_stack_item_s {
58     gs_font *font;		/* font at this level */
59     uint index;			/* index of this font in parent's Encoding */
60 } gx_font_stack_item_t;
61 typedef struct gx_font_stack_s {
62     int depth;
63     gx_font_stack_item_t items[1 + MAX_FONT_STACK];
64 } gx_font_stack_t;
65 
66 /*
67  * Define the common part of the structure that tracks the state of text
68  * processing.  All implementations of text_begin must allocate one of these
69  * using rc_alloc_struct_1; implementations may subclass and extend it.
70  * Note that it includes a copy of the text parameters.
71  *
72  * The freeing procedure (rc.free) must call rc_free_text_enum, which
73  * calls the enumerator's release procedure.  This is required in order to
74  * properly decrement the reference count(s) of the referenced structures
75  * (in the common part of the structure, only the device).
76  */
77 rc_free_proc(rc_free_text_enum);
78 #define gs_text_enum_common\
79     /*\
80      * The following copies of the arguments of text_begin are set at\
81      * initialization, and const thereafter.\
82      */\
83     gs_text_params_t text;	/* must be first for subclassing */\
84     gx_device *dev;\
85     gx_device *imaging_dev;	/* see note below */\
86     gs_imager_state *pis;\
87     gs_font *orig_font;\
88     gx_path *path;			/* unless DO_NONE & !RETURN_WIDTH */\
89     const gx_device_color *pdcolor;	/* if DO_DRAW */\
90     const gx_clip_path *pcpath;		/* if DO_DRAW */\
91     gs_memory_t *memory;\
92     /* The following additional members are set at initialization. */\
93     const gs_text_enum_procs_t *procs;\
94     /* The following change dynamically.  NOTE: gs_text_enum_copy_dynamic */\
95     /* knows the entire list of dynamically changing elements. */\
96     rc_header rc;\
97     gs_font *current_font; /* changes for composite fonts */\
98     gs_glyph outer_CID; /* When a Type 3 is a FMapType 9 descendent. */\
99     bool is_pure_color; /* The text is painted with a pure color. */\
100     gs_log2_scale_point log2_scale;	/* for oversampling */\
101     cached_fm_pair *pair; /* corresponds to the current_font and CTM*(1<<log2_scale) */\
102     uint index;			/* index within string */\
103     uint xy_index;		/* index within X/Y widths */\
104     gx_font_stack_t fstack;\
105     int cmap_code;		/* hack for FMapType 9 composite fonts, */\
106 				/* the value returned by decode_next */\
107     gs_point FontBBox_as_Metrics2;  /* used with FontType 9,11 && WMode 1 */\
108     /* The following is controlled by a device. */\
109     bool device_disabled_grid_fitting;\
110     /* The following are used to return information to the client. */\
111     gs_text_returned_t returned
112 /* The typedef is in gstext.h. */
113 struct gs_text_enum_s {
114     gs_text_enum_common;
115 };
116 
117 /*
118  * Notes on the imaging_dev field of device enumeration structures:
119  *
120  * This field is added as a hack to make the bbox device work
121  * correctly as a forwarding device in some cases, particularly the X
122  * driver. When the X driver is configured to use a memory device for
123  * rendering (ie the MaxBitmap parameter is large enough to hold the
124  * buffer), it sets up a pipeline where the bbox device forwards to
125  * the memory device. The bbox device is used to determine which areas
126  * of the buffer have been drawn on, so that the screen can be
127  * appropriately updated.
128  *
129  * This works well for low-level operations such as filling
130  * rectangles, because the bbox device can easily determine the bbox
131  * of the drawing operation before forwarding it to the target device.
132  * However, for higher level operations, such as those that require
133  * enumerators, the approach is fundamentally broken. Essentially, the
134  * execution of the drawing operation is the responsibility of the
135  * target device, and the bbox device doesn't really have any way to
136  * determine the bounding box.
137  *
138  * The approach taken here is to add an additional field to the
139  * enumerations, imaging_dev. In the common case where the target
140  * device implements the high level drawing operation in terms of
141  * lower level operations, setting the imaging_dev field to non-NULL
142  * requests that these lower level imaging operations be directed to
143  * the imaging_dev rather than dev. The bbox device sets the
144  * imaging_dev field to point to itself. Thus, the low level drawing
145  * operations are intercepted by the bbox device, so that the bbox is
146  * accounted for.
147  *
148  * Note that, if the target device implements higher level operations
149  * by itself, ie not by breaking it into lower level operations, this
150  * approach will fail.
151  */
152 
153 #define st_gs_text_enum_max_ptrs (st_gs_text_params_max_ptrs + 8)
154 /*extern_st(st_gs_text_enum); */
155 #define public_st_gs_text_enum()	/* in gstext.c */\
156   gs_public_st_composite(st_gs_text_enum, gs_text_enum_t, "gs_text_enum_t",\
157     text_enum_enum_ptrs, text_enum_reloc_ptrs)
158 
159 /*
160  * Initialize a newly created text enumerator.  Implementations of
161  * text_begin must call this just after allocating the enumerator.
162  * Note that this procedure can return an error, e.g., if attempting
163  * a glyph-based operation with a composite font.
164  */
165 int gs_text_enum_init(gs_text_enum_t *pte,
166 		      const gs_text_enum_procs_t *procs,
167 		      gx_device *dev, gs_imager_state *pis,
168 		      const gs_text_params_t *text,
169 		      gs_font *font, gx_path *path,
170 		      const gx_device_color *pdcolor,
171 		      const gx_clip_path *pcpath,
172 		      gs_memory_t *mem);
173 
174 /*
175  * Copy the dynamically changing elements from one enumerator to another.
176  * This is useful primarily for enumerators that sometimes pass the
177  * operation to a subsidiary enumerator.  Note that `returned' is copied
178  * iff for_return is true.
179  */
180 void gs_text_enum_copy_dynamic(gs_text_enum_t *pto,
181 			       const gs_text_enum_t *pfrom,
182 			       bool for_return);
183 
184 /*
185  * Define some convenience macros for testing aspects of a text
186  * enumerator.
187  */
188 
189 #define SHOW_IS(penum, op_mask)\
190   (((penum)->text.operation & (op_mask)) != 0)
191 #define SHOW_IS_ALL_OF(penum, op_mask)\
192   (((penum)->text.operation & (op_mask)) == (op_mask))
193     /*
194      * The comments next to the following macros indicate the
195      * corresponding test on gs_show_enum structures in pre-5.24 filesets.
196      */
197 #define SHOW_IS_ADD_TO_ALL(penum)	/* add */\
198   SHOW_IS(penum, TEXT_ADD_TO_ALL_WIDTHS)
199 #define SHOW_IS_ADD_TO_SPACE(penum)	/* wchr != no_char */\
200   SHOW_IS(penum, TEXT_ADD_TO_SPACE_WIDTH)
201 #define SHOW_IS_DO_KERN(penum)		/* do_kern */\
202   SHOW_IS(penum, TEXT_INTERVENE)
203 #define SHOW_IS_SLOW(penum)		/* slow_show */\
204   SHOW_IS(penum, TEXT_REPLACE_WIDTHS | TEXT_ADD_TO_ALL_WIDTHS | TEXT_ADD_TO_SPACE_WIDTH | TEXT_INTERVENE)
205 #define SHOW_IS_DRAWING(penum)		/* !stringwidth_flag */\
206   !SHOW_IS(penum, TEXT_DO_NONE)
207 #define SHOW_IS_STRINGWIDTH(penum)	/* stringwidth_flag > 0 */\
208   SHOW_IS_ALL_OF(penum, TEXT_DO_NONE | TEXT_RETURN_WIDTH)
209 
210 /*
211  * Define the procedures associated with text processing.
212  */
213 struct gs_text_enum_procs_s {
214 
215     /*
216      * Resync processing from an enumerator that may have different
217      * parameters and may be partway through processing the string.  Note
218      * that this may only be implemented for certain kinds of changes, and
219      * will fail for other kinds.  (We may reconsider this.)  We require
220      * pfrom != pte.
221      */
222 
223 #define text_enum_proc_resync(proc)\
224   int proc(gs_text_enum_t *pte, const gs_text_enum_t *pfrom)
225 
226     text_enum_proc_resync((*resync));
227 
228     /*
229      * Process the text.  The client should call this repeatedly until
230      * it returns <= 0.  (> 0 means the client must take action: see
231      * gstext.h.)
232      *
233      * Note that a default implementation of this procedure can't simply do
234      * nothing and return:
235      *
236      *   - If TEXT_DO_CHARWIDTH or TEXT_DO_*PATH is set, the procedure must
237      *   append the appropriate elements to the path.
238      *
239      *   - If TEXT_INTERVENE is set, the procedure must return to the client
240      *   after each character except the last one in the string, setting
241      *   returned.current_char and returned.current_glyph appropriately;
242      *   also, it must reset the current font in the graphics state to its
243      *   original value each time each time (after the first) that the
244      *   procedure is called to process further characters of the string.
245      *
246      *   - If TEXT_RETURN_WIDTH is set, the procedure must set
247      *   returned.total_width when(ever) it returns.
248      *
249      * We should provide a default implementation that makes all these
250      * things simple, but currently we don't.
251      */
252 
253 #define text_enum_proc_process(proc)\
254   int proc(gs_text_enum_t *pte)
255 
256     text_enum_proc_process((*process));
257 
258     /*
259      * After the implementation returned TEXT_PROCESS_RENDER, determine
260      * whether it needs the entire character description, or only the width
261      * (escapement).
262      */
263 
264 #define text_enum_proc_is_width_only(proc)\
265   bool proc(const gs_text_enum_t *pte)
266 
267     text_enum_proc_is_width_only((*is_width_only));
268 
269     /*
270      * Return the width of the current character (in user space coordinates).
271      */
272 
273 #define text_enum_proc_current_width(proc)\
274   int proc(const gs_text_enum_t *pte, gs_point *pwidth)
275 
276     text_enum_proc_current_width((*current_width));
277 
278     /*
279      * Set the character width and optionally the bounding box,
280      * and optionally enable caching.
281      */
282 
283 #define text_enum_proc_set_cache(proc)\
284   int proc(gs_text_enum_t *pte, const double *values,\
285     gs_text_cache_control_t control)
286 
287     text_enum_proc_set_cache((*set_cache));
288 
289     /*
290      * Prepare to retry processing the current character by uninstalling the
291      * cache device.
292      */
293 
294 #define text_enum_proc_retry(proc)\
295   int proc(gs_text_enum_t *pte)
296 
297     text_enum_proc_retry((*retry));
298 
299     /*
300      * Release the contents of the structure at the end of processing,
301      * but don't free the structure itself.  (gs_text_release also does
302      * the latter.)
303      */
304 
305 #define text_enum_proc_release(proc)\
306   void proc(gs_text_enum_t *pte, client_name_t cname)
307 
308     text_enum_proc_release((*release));
309 
310 };
311 
312 /* Define the default release procedure. */
313 text_enum_proc_release(gx_default_text_release);
314 
315 #endif /* gxtext_INCLUDED */
316