1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
14
/* $Id: gxtext.h 8022 2007-06-05 22:23:38Z giles $ */
15
/* Driver text interface implementation support */
17
#ifndef gxtext_INCLUDED
18
# define gxtext_INCLUDED
23
/* Define the abstract type for the object procedures. */
24
typedef struct gs_text_enum_procs_s gs_text_enum_procs_t;
26
#ifndef cached_fm_pair_DEFINED
27
# define cached_fm_pair_DEFINED
28
typedef struct cached_fm_pair_s cached_fm_pair;
32
* Define values returned by text_process to the client.
34
typedef struct gs_text_returned_s {
35
gs_char current_char; /* INTERVENE */
36
gs_glyph current_glyph; /* INTERVENE */
37
gs_point total_width; /* RETURN_WIDTH */
41
* Define the stack for composite fonts.
42
* If the current font is not composite, depth = -1.
43
* If the current font is composite, 0 <= depth <= MAX_FONT_STACK.
44
* items[0] through items[depth] are occupied.
45
* items[0].font is the root font; items[0].index = 0.
46
* The root font must be composite, but may be of any map type.
47
* items[0..N-1] are modal composite fonts, for some N <= depth.
48
* items[N..depth-1] are non-modal composite fonts.
49
* items[depth] is a base (non-composite) font.
50
* Note that if depth >= 0, the font member of the graphics state
51
* for a base font BuildChar/Glyph is the same as items[depth].font.
53
#define MAX_FONT_STACK 5
54
typedef struct gx_font_stack_item_s {
55
gs_font *font; /* font at this level */
56
uint index; /* index of this font in parent's Encoding */
57
} gx_font_stack_item_t;
58
typedef struct gx_font_stack_s {
60
gx_font_stack_item_t items[1 + MAX_FONT_STACK];
64
* Define the common part of the structure that tracks the state of text
65
* processing. All implementations of text_begin must allocate one of these
66
* using rc_alloc_struct_1; implementations may subclass and extend it.
67
* Note that it includes a copy of the text parameters.
69
* The freeing procedure (rc.free) must call rc_free_text_enum, which
70
* calls the enumerator's release procedure. This is required in order to
71
* properly decrement the reference count(s) of the referenced structures
72
* (in the common part of the structure, only the device).
74
rc_free_proc(rc_free_text_enum);
75
#define gs_text_enum_common\
77
* The following copies of the arguments of text_begin are set at\
78
* initialization, and const thereafter.\
80
gs_text_params_t text; /* must be first for subclassing */\
82
gx_device *imaging_dev; /* see note below */\
83
gs_imager_state *pis;\
85
gx_path *path; /* unless DO_NONE & !RETURN_WIDTH */\
86
const gx_device_color *pdcolor; /* if DO_DRAW */\
87
const gx_clip_path *pcpath; /* if DO_DRAW */\
89
/* The following additional members are set at initialization. */\
90
const gs_text_enum_procs_t *procs;\
91
/* The following change dynamically. NOTE: gs_text_enum_copy_dynamic */\
92
/* knows the entire list of dynamically changing elements. */\
94
void *enum_client_data;\
95
gs_font *current_font; /* changes for composite fonts */\
96
gs_glyph outer_CID; /* When a Type 3 is a FMapType 9 descendent. */\
97
bool is_pure_color; /* The text is painted with a pure color. */\
98
gs_log2_scale_point log2_scale; /* for oversampling */\
99
cached_fm_pair *pair; /* corresponds to the current_font and CTM*(1<<log2_scale) */\
100
uint index; /* index within string */\
101
uint xy_index; /* index within X/Y widths */\
102
gx_font_stack_t fstack;\
103
int cmap_code; /* hack for FMapType 9 composite fonts, */\
104
/* the value returned by decode_next */\
105
gs_point FontBBox_as_Metrics2; /* used with FontType 9,11 && WMode 1 */\
106
ulong text_enum_id; /* debug purpose only - not used by algorythm. */\
107
/* The following is controlled by a device. */\
108
bool device_disabled_grid_fitting;\
109
/* The following are used to return information to the client. */\
110
gs_text_returned_t returned
111
/* The typedef is in gstext.h. */
112
struct gs_text_enum_s {
117
* Notes on the imaging_dev field of device enumeration structures:
119
* This field is added as a hack to make the bbox device work
120
* correctly as a forwarding device in some cases, particularly the X
121
* driver. When the X driver is configured to use a memory device for
122
* rendering (ie the MaxBitmap parameter is large enough to hold the
123
* buffer), it sets up a pipeline where the bbox device forwards to
124
* the memory device. The bbox device is used to determine which areas
125
* of the buffer have been drawn on, so that the screen can be
126
* appropriately updated.
128
* This works well for low-level operations such as filling
129
* rectangles, because the bbox device can easily determine the bbox
130
* of the drawing operation before forwarding it to the target device.
131
* However, for higher level operations, such as those that require
132
* enumerators, the approach is fundamentally broken. Essentially, the
133
* execution of the drawing operation is the responsibility of the
134
* target device, and the bbox device doesn't really have any way to
135
* determine the bounding box.
137
* The approach taken here is to add an additional field to the
138
* enumerations, imaging_dev. In the common case where the target
139
* device implements the high level drawing operation in terms of
140
* lower level operations, setting the imaging_dev field to non-NULL
141
* requests that these lower level imaging operations be directed to
142
* the imaging_dev rather than dev. The bbox device sets the
143
* imaging_dev field to point to itself. Thus, the low level drawing
144
* operations are intercepted by the bbox device, so that the bbox is
147
* Note that, if the target device implements higher level operations
148
* by itself, ie not by breaking it into lower level operations, this
149
* approach will fail.
152
#define st_gs_text_enum_max_ptrs (st_gs_text_params_max_ptrs + 8)
153
/*extern_st(st_gs_text_enum); */
154
#define public_st_gs_text_enum() /* in gstext.c */\
155
gs_public_st_composite(st_gs_text_enum, gs_text_enum_t, "gs_text_enum_t",\
156
text_enum_enum_ptrs, text_enum_reloc_ptrs)
159
* Initialize a newly created text enumerator. Implementations of
160
* text_begin must call this just after allocating the enumerator.
161
* Note that this procedure can return an error, e.g., if attempting
162
* a glyph-based operation with a composite font.
164
int gs_text_enum_init(gs_text_enum_t *pte,
165
const gs_text_enum_procs_t *procs,
166
gx_device *dev, gs_imager_state *pis,
167
const gs_text_params_t *text,
168
gs_font *font, gx_path *path,
169
const gx_device_color *pdcolor,
170
const gx_clip_path *pcpath,
174
* Copy the dynamically changing elements from one enumerator to another.
175
* This is useful primarily for enumerators that sometimes pass the
176
* operation to a subsidiary enumerator. Note that `returned' is copied
177
* iff for_return is true.
179
void gs_text_enum_copy_dynamic(gs_text_enum_t *pto,
180
const gs_text_enum_t *pfrom,
184
* Define some convenience macros for testing aspects of a text
188
#define SHOW_IS(penum, op_mask)\
189
(((penum)->text.operation & (op_mask)) != 0)
190
#define SHOW_IS_ALL_OF(penum, op_mask)\
191
(((penum)->text.operation & (op_mask)) == (op_mask))
193
* The comments next to the following macros indicate the
194
* corresponding test on gs_show_enum structures in pre-5.24 filesets.
196
#define SHOW_IS_ADD_TO_ALL(penum) /* add */\
197
SHOW_IS(penum, TEXT_ADD_TO_ALL_WIDTHS)
198
#define SHOW_IS_ADD_TO_SPACE(penum) /* wchr != no_char */\
199
SHOW_IS(penum, TEXT_ADD_TO_SPACE_WIDTH)
200
#define SHOW_IS_DO_KERN(penum) /* do_kern */\
201
SHOW_IS(penum, TEXT_INTERVENE)
202
#define SHOW_IS_SLOW(penum) /* slow_show */\
203
SHOW_IS(penum, TEXT_REPLACE_WIDTHS | TEXT_ADD_TO_ALL_WIDTHS | TEXT_ADD_TO_SPACE_WIDTH | TEXT_INTERVENE)
204
#define SHOW_IS_DRAWING(penum) /* !stringwidth_flag */\
205
!SHOW_IS(penum, TEXT_DO_NONE)
206
#define SHOW_IS_STRINGWIDTH(penum) /* stringwidth_flag > 0 */\
207
SHOW_IS_ALL_OF(penum, TEXT_DO_NONE | TEXT_RETURN_WIDTH)
210
* Define the procedures associated with text processing.
212
struct gs_text_enum_procs_s {
215
* Resync processing from an enumerator that may have different
216
* parameters and may be partway through processing the string. Note
217
* that this may only be implemented for certain kinds of changes, and
218
* will fail for other kinds. (We may reconsider this.) We require
222
#define text_enum_proc_resync(proc)\
223
int proc(gs_text_enum_t *pte, const gs_text_enum_t *pfrom)
225
text_enum_proc_resync((*resync));
228
* Process the text. The client should call this repeatedly until
229
* it returns <= 0. (> 0 means the client must take action: see
232
* Note that a default implementation of this procedure can't simply do
233
* nothing and return:
235
* - If TEXT_DO_CHARWIDTH or TEXT_DO_*PATH is set, the procedure must
236
* append the appropriate elements to the path.
238
* - If TEXT_INTERVENE is set, the procedure must return to the client
239
* after each character except the last one in the string, setting
240
* returned.current_char and returned.current_glyph appropriately;
241
* also, it must reset the current font in the graphics state to its
242
* original value each time each time (after the first) that the
243
* procedure is called to process further characters of the string.
245
* - If TEXT_RETURN_WIDTH is set, the procedure must set
246
* returned.total_width when(ever) it returns.
248
* We should provide a default implementation that makes all these
249
* things simple, but currently we don't.
252
#define text_enum_proc_process(proc)\
253
int proc(gs_text_enum_t *pte)
255
text_enum_proc_process((*process));
258
* After the implementation returned TEXT_PROCESS_RENDER, determine
259
* whether it needs the entire character description, or only the width
263
#define text_enum_proc_is_width_only(proc)\
264
bool proc(const gs_text_enum_t *pte)
266
text_enum_proc_is_width_only((*is_width_only));
269
* Return the width of the current character (in user space coordinates).
272
#define text_enum_proc_current_width(proc)\
273
int proc(const gs_text_enum_t *pte, gs_point *pwidth)
275
text_enum_proc_current_width((*current_width));
278
* Set the character width and optionally the bounding box,
279
* and optionally enable caching.
282
#define text_enum_proc_set_cache(proc)\
283
int proc(gs_text_enum_t *pte, const double *values,\
284
gs_text_cache_control_t control)
286
text_enum_proc_set_cache((*set_cache));
289
* Prepare to retry processing the current character by uninstalling the
293
#define text_enum_proc_retry(proc)\
294
int proc(gs_text_enum_t *pte)
296
text_enum_proc_retry((*retry));
299
* Release the contents of the structure at the end of processing,
300
* but don't free the structure itself. (gs_text_release also does
304
#define text_enum_proc_release(proc)\
305
void proc(gs_text_enum_t *pte, client_name_t cname)
307
text_enum_proc_release((*release));
311
/* Define the default release procedure. */
312
text_enum_proc_release(gx_default_text_release);
314
#endif /* gxtext_INCLUDED */