1 /* Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14 */
15
16
17 /* Fast case character cache routines for Ghostscript library */
18 #include "memory_.h"
19 #include "gx.h"
20 #include "gpcheck.h"
21 #include "gserrors.h"
22 #include "gsstruct.h"
23 #include "gscencs.h"
24 #include "gxfixed.h"
25 #include "gxmatrix.h"
26 #include "gzstate.h"
27 #include "gzpath.h"
28 #include "gxdevice.h"
29 #include "gxdevmem.h"
30 #include "gzcpath.h"
31 #include "gxchar.h"
32 #include "gxfont.h"
33 #include "gxfcache.h"
34 #include "gxxfont.h"
35 #include "gximask.h"
36 #include "gscspace.h" /* for gsimage.h */
37 #include "gsimage.h"
38 #include "gxhttile.h"
39 #include "gsptype1.h" /* for gx_dc_is_pattern1_color_with_trans */
40
41 /* Forward references */
42 static byte *compress_alpha_bits(const cached_char *, gs_memory_t *);
43
44 /* Define a scale factor of 1. */
45 static const gs_log2_scale_point scale_log2_1 =
46 {0, 0};
47
48 void
gx_compute_char_matrix(const gs_matrix * char_tm,const gs_log2_scale_point * log2_scale,float * mxx,float * mxy,float * myx,float * myy)49 gx_compute_char_matrix(const gs_matrix *char_tm, const gs_log2_scale_point *log2_scale,
50 float *mxx, float *mxy, float *myx, float *myy)
51 {
52 int scale_x = 1 << log2_scale->x;
53 int scale_y = 1 << log2_scale->y;
54
55 *mxx = char_tm->xx * scale_x;
56 *mxy = char_tm->xy * scale_x;
57 *myx = char_tm->yx * scale_y;
58 *myy = char_tm->yy * scale_y;
59 }
60
61 void
gx_compute_ccache_key(gs_font * pfont,const gs_matrix * char_tm,const gs_log2_scale_point * log2_scale,bool design_grid,float * mxx,float * mxy,float * myx,float * myy)62 gx_compute_ccache_key(gs_font * pfont, const gs_matrix *char_tm,
63 const gs_log2_scale_point *log2_scale, bool design_grid,
64 float *mxx, float *mxy, float *myx, float *myy)
65 {
66 if (design_grid &&
67 (pfont->FontType == ft_TrueType || pfont->FontType == ft_CID_TrueType)) {
68 /*
69 * We need a special face for this case, because the TT interpreter
70 * can't generate both grid_fitted and non-grid-fitted outlines
71 * with a same face instance. This happens due to control
72 * values in 'cvt' must be different.
73 * Since a single face satisfies all font sizes,
74 * we use a zero matrix as the cache entry key.
75 */
76 *mxx = *mxy = *myx = *myy = 0;
77 } else
78 gx_compute_char_matrix(char_tm, log2_scale, mxx, mxy, myx, myy);
79 }
80
81 /* Look up, and if necessary add, a font/matrix pair in the cache */
82 int
gx_lookup_fm_pair(gs_font * pfont,const gs_matrix * char_tm,const gs_log2_scale_point * log2_scale,bool design_grid,cached_fm_pair ** ppair)83 gx_lookup_fm_pair(gs_font * pfont, const gs_matrix *char_tm,
84 const gs_log2_scale_point *log2_scale, bool design_grid, cached_fm_pair **ppair)
85 {
86 float mxx, mxy, myx, myy;
87 gs_font *font = pfont;
88 register gs_font_dir *dir = font->dir;
89 register cached_fm_pair *pair = dir->fmcache.mdata + dir->fmcache.used;
90 int count = dir->fmcache.msize;
91 gs_uid uid;
92
93 gx_compute_ccache_key(pfont, char_tm, log2_scale, design_grid,
94 &mxx, &mxy, &myx, &myy);
95 if (font->FontType == ft_composite || font->PaintType != 0) { /* We can't cache by UID alone. */
96 uid_set_invalid(&uid);
97 } else {
98 uid = ((gs_font_base *) font)->UID;
99 if (uid_is_valid(&uid))
100 font = 0;
101 }
102 for (;count--; pair = dir->fmcache.mdata + pair->next) {
103 /* We have either a non-zero font and an invalid UID, */
104 /* or a zero font and a valid UID. */
105 /* We have to break up the test */
106 /* because of a bug in the Zortech compiler. */
107 if (font != 0) {
108 if (pair->font != font)
109 continue;
110 } else {
111 if (!uid_equal(&pair->UID, &uid) ||
112 pair->FontType != pfont->FontType
113 )
114 continue;
115 }
116 if (pair->mxx == mxx && pair->mxy == mxy &&
117 pair->myx == myx && pair->myy == myy
118 && pair->design_grid == design_grid) {
119 int code;
120
121 if (pair->font == 0) {
122 pair->font = pfont;
123 if_debug2('k', "[k]updating pair 0x%lx with font 0x%lx\n",
124 (ulong) pair, (ulong) pfont);
125 } else {
126 if_debug2('k', "[k]found pair 0x%lx: font=0x%lx\n",
127 (ulong) pair, (ulong) pair->font);
128 }
129 code = gx_touch_fm_pair(dir, pair);
130 if (code < 0)
131 return code;
132 code = gx_provide_fm_pair_attributes(dir, pfont, pair,
133 char_tm, log2_scale, design_grid);
134 if (code < 0)
135 return code;
136 *ppair = pair;
137 return 0;
138 }
139 }
140 return gx_add_fm_pair(dir, pfont, &uid, char_tm, log2_scale, design_grid, ppair);
141 }
142
143 /* Look up a glyph with the right depth in the cache. */
144 /* Return the cached_char or 0. */
145 cached_char *
gx_lookup_cached_char(const gs_font * pfont,const cached_fm_pair * pair,gs_glyph glyph,int wmode,int depth,gs_fixed_point * subpix_origin)146 gx_lookup_cached_char(const gs_font * pfont, const cached_fm_pair * pair,
147 gs_glyph glyph, int wmode, int depth,
148 gs_fixed_point *subpix_origin)
149 {
150 gs_font_dir *dir = pfont->dir;
151 uint chi = chars_head_index(glyph, pair);
152 register cached_char *cc;
153
154 while ((cc = dir->ccache.table[chi & dir->ccache.table_mask]) != 0) {
155 if (cc->code == glyph && cc_pair(cc) == pair &&
156 cc->subpix_origin.x == subpix_origin->x &&
157 cc->subpix_origin.y == subpix_origin->y &&
158 cc->wmode == wmode && cc_depth(cc) == depth
159 ) {
160 if_debug4('K', "[K]found 0x%lx (depth=%d) for glyph=0x%lx, wmode=%d\n",
161 (ulong) cc, cc_depth(cc), (ulong) glyph, wmode);
162 return cc;
163 }
164 chi++;
165 }
166 if_debug3('K', "[K]not found: glyph=0x%lx, wmode=%d, depth=%d\n",
167 (ulong) glyph, wmode, depth);
168 return 0;
169 }
170
171 /* Copy a cached character to the screen. */
172 /* Assume the caller has already done gx_color_load. */
173 /* Return 0 if OK, 1 if we couldn't do the operation but no error */
174 /* should be signalled, or a negative error code. */
175 int
gx_image_cached_char(register gs_show_enum * penum,register cached_char * cc)176 gx_image_cached_char(register gs_show_enum * penum, register cached_char * cc)
177 {
178 register gs_state *pgs = penum->pgs;
179 gx_device_color *pdevc = gs_currentdevicecolor_inline(pgs);
180 int x, y, w, h, depth;
181 int code;
182 gs_fixed_point pt;
183 gx_device *dev = penum->dev;
184 gx_device *imaging_dev = penum->imaging_dev ? penum->imaging_dev : dev;
185 gx_device *orig_dev = imaging_dev;
186 gx_device_clip cdev;
187 gx_xglyph xg = cc->xglyph;
188 gx_xfont *xf;
189 byte *bits;
190
191 top:code = gx_path_current_point_inline(pgs, &pt);
192 if (code < 0)
193 return code;
194 /*
195 * If the character doesn't lie entirely within the inner
196 * clipping rectangle, we set up an intermediate clipping device.
197 * Note that if the original device implements fill_mask, we may
198 * never actually use the clipping device.
199 */
200 pt.x -= cc->offset.x + cc->subpix_origin.x;
201 x = fixed2int_var_rounded(pt.x) + penum->ftx;
202 pt.y -= cc->offset.y + cc->subpix_origin.y;
203 y = fixed2int_var_rounded(pt.y) + penum->fty;
204 w = cc->width;
205 h = cc->height;
206 #ifdef DEBUG
207 if (gs_debug_c('K')) {
208 if (cc_has_bits(cc))
209 debug_dump_bitmap(cc_bits(cc), cc_raster(cc), h,
210 "[K]bits");
211 else
212 dputs("[K]no bits\n");
213 dlprintf3("[K]copying 0x%lx, offset=(%g,%g)\n", (ulong) cc,
214 fixed2float(-cc->offset.x),
215 fixed2float(-cc->offset.y));
216 dlprintf6(" at (%g,%g)+(%d,%d)->(%d,%d)\n",
217 fixed2float(pt.x), fixed2float(pt.y),
218 penum->ftx, penum->fty, x, y);
219 }
220 #endif
221 if ((x < penum->ibox.p.x || x + w > penum->ibox.q.x ||
222 y < penum->ibox.p.y || y + h > penum->ibox.q.y) &&
223 imaging_dev != (gx_device *) & cdev /* might be 2nd time around */
224 ) { /* Check for the character falling entirely outside */
225 /* the clipping region. */
226 gx_clip_path *pcpath;
227
228 if (x >= penum->obox.q.x || x + w <= penum->obox.p.x ||
229 y >= penum->obox.q.y || y + h <= penum->obox.p.y
230 )
231 return 0; /* nothing to do */
232 code = gx_effective_clip_path(pgs, &pcpath);
233 if (code < 0)
234 return code;
235 gx_make_clip_device_on_stack(&cdev, pcpath, imaging_dev);
236 imaging_dev = (gx_device *) & cdev;
237 if_debug0('K', "[K](clipping)\n");
238 }
239 code = gx_set_dev_color(pgs);
240 if (code != 0)
241 return code;
242 /* If an xfont can render this character, use it. */
243 if (xg != gx_no_xglyph && (xf = cc_pair(cc)->xfont) != 0) {
244 int cx = x + fixed2int(cc->offset.x);
245 int cy = y + fixed2int(cc->offset.y);
246
247 /*
248 * Note that we prefer a 1-bit xfont implementation over
249 * a multi-bit cached bitmap. Eventually we should change
250 * the xfont interface so it can deliver multi-bit bitmaps,
251 * or else implement oversampling for xfonts.
252 */
253 if (gs_color_writes_pure(pgs)) {
254 code = (*xf->common.procs->render_char) (xf, xg,
255 imaging_dev, cx, cy,
256 pdevc->colors.pure, 0);
257 if_debug8('K', "[K]render_char display: xfont=0x%lx, glyph=0x%lx\n\tdev=0x%lx(%s) x,y=%d,%d, color=0x%lx => %d\n",
258 (ulong) xf, (ulong) xg, (ulong) imaging_dev,
259 imaging_dev->dname, cx, cy,
260 (ulong) pdevc->colors.pure, code);
261 if (code == 0)
262 return_check_interrupt(penum->memory, 0);
263 }
264 /* Can't render directly. If we don't have a bitmap yet, */
265 /* get it from the xfont now. */
266 if (!cc_has_bits(cc)) {
267 gx_device_memory mdev;
268
269 gs_make_mem_mono_device(&mdev, dev->memory, imaging_dev);
270 gx_open_cache_device(&mdev, cc);
271 code = (*xf->common.procs->render_char) (xf, xg,
272 (gx_device *) & mdev, cx - x, cy - y,
273 (gx_color_index) 1, 1);
274 if_debug7('K', "[K]render_char to bits: xfont=0x%lx, glyph=0x%lx\n\tdev=0x%lx(%s) x,y=%d,%d => %d\n",
275 (ulong) xf, (ulong) xg, (ulong) & mdev,
276 mdev.dname, cx - x, cy - y, code);
277 if (code != 0)
278 return_check_interrupt(penum->memory, 1);
279 gx_add_char_bits(cc_pair(cc)->font->dir,
280 cc, &scale_log2_1);
281 /* gx_add_char_bits may change width, height, */
282 /* raster, and/or offset. It's easiest to */
283 /* start over from the top. Clear xg so that */
284 /* we don't waste time trying render_char again. */
285 xg = gx_no_xglyph;
286 goto top;
287 }
288 }
289 /*
290 * No xfont. Render from the cached bits. If the cached bits
291 * have more than 1 bit of alpha, and the color isn't pure or
292 * the copy_alpha operation fails, construct a single-bit mask
293 * by taking the high-order alpha bit.
294 */
295 bits = cc_bits(cc);
296 /* With 4x2 scale, depth == 3.
297 * An example is -dTextAlphaBits=4 comparefiles/fonttest.pdf .
298 * We need to map 4 bitmap bits to 2 alpha bits.
299 */
300 depth = (cc_depth(cc) == 3 ? 2 : cc_depth(cc));
301 if ((dev_proc(orig_dev, fill_mask) != gx_default_fill_mask ||
302 !lop_no_S_is_T(pgs->log_op))) {
303
304 gx_clip_path *pcpath;
305
306 if (penum) {
307 penum->use_wxy_float = false;
308 penum->wxy_float.x = penum->wxy_float.y = 0.0;
309 penum->wxy = cc->wxy;
310 }
311
312 code = gx_effective_clip_path(pgs, &pcpath);
313 if (code >= 0) {
314 code = gx_image_fill_masked
315 (orig_dev, bits, 0, cc_raster(cc), cc->id,
316 x, y, w, h, pdevc, depth, pgs->log_op, pcpath);
317 if (code >= 0)
318 goto done;
319 }
320 } else if (gs_color_writes_pure(pgs)) {
321 gx_color_index color = pdevc->colors.pure;
322
323 if (depth > 1) {
324 code = (*dev_proc(imaging_dev, copy_alpha))
325 (imaging_dev, bits, 0, cc_raster(cc), cc->id,
326 x, y, w, h, color, depth);
327 if (code >= 0)
328 return_check_interrupt(penum->memory, 0);
329 /* copy_alpha failed, construct a monobit mask. */
330 bits = compress_alpha_bits(cc, penum->memory->non_gc_memory);
331 if (bits == 0)
332 return 1; /* VMerror, but recoverable */
333 }
334 code = (*dev_proc(imaging_dev, copy_mono))
335 (imaging_dev, bits, 0, bitmap_raster(w), gs_no_id,
336 x, y, w, h, gx_no_color_index, color);
337 goto done;
338 }
339 if (depth > 1) { /* Complex color or fill_mask / copy_alpha failed, */
340 /* construct a monobit mask. */
341 bits = compress_alpha_bits(cc, penum->memory->non_gc_memory);
342 if (bits == 0)
343 return 1; /* VMerror, but recoverable */
344
345 } { /* Use imagemask to render the character. */
346 gs_memory_t *mem = penum->memory->non_gc_memory;
347 gs_image_enum *pie =
348 gs_image_enum_alloc(mem, "image_char(image_enum)");
349 gs_image_t image;
350 int iy;
351 uint used, raster = (bits == cc_bits(cc) ? cc_raster(cc)
352 : bitmap_raster(cc->width) );
353 int code1;
354
355 if (pie == 0) {
356 if (bits != cc_bits(cc))
357 gs_free_object(mem, bits,
358 "compress_alpha_bits");
359 return 1; /* VMerror, but recoverable */
360 }
361 /* Make a matrix that will place the image */
362 /* at (x,y) with no transformation. */
363 gs_image_t_init_mask(&image, true);
364 gs_make_translation((floatp) - x, (floatp) - y, &image.ImageMatrix);
365 gs_matrix_multiply(&ctm_only(pgs), &image.ImageMatrix, &image.ImageMatrix);
366 image.Width = w;
367 image.Height = h;
368 image.adjust = false;
369 code = gs_image_init(pie, &image, false, pgs);
370 switch (code) {
371 case 1: /* empty image */
372 code = 0;
373 default:
374 break;
375 case 0:
376 for (iy = 0; iy < h && code >= 0; iy++)
377 code = gs_image_next(pie, bits + iy * raster,
378 (w + 7) >> 3, &used);
379 }
380 code1 = gs_image_cleanup_and_free_enum(pie, pgs);
381 if (code >= 0 && code1 < 0)
382 code = code1;
383 }
384 done:if (bits != cc_bits(cc))
385 gs_free_object(penum->memory->non_gc_memory, bits, "compress_alpha_bits");
386 if (code > 0)
387 code = 0;
388 return_check_interrupt(penum->memory, code);
389 }
390
391 /* ------ Image manipulation ------ */
392
393 /*
394 * Compress a mask with 2 or 4 bits of alpha to a monobit mask.
395 * Allocate and return the address of the monobit mask.
396 */
397 static byte *
compress_alpha_bits(const cached_char * cc,gs_memory_t * mem)398 compress_alpha_bits(const cached_char * cc, gs_memory_t * mem)
399 {
400 const byte *data = cc_const_bits(cc);
401 uint width = cc->width;
402 uint height = cc->height;
403 /* With 4x2 scale, depth == 3.
404 * An example is -dTextAlphaBits=4 comparefiles/fonttest.pdf .
405 * We need to map 4 bitmap bits to 2 alpha bits.
406 */
407 int depth = (cc_depth(cc) == 3 ? 2 : cc_depth(cc));
408 uint sraster = cc_raster(cc);
409 uint sskip = sraster - ((width * depth + 7) >> 3);
410 uint draster = bitmap_raster(width);
411 uint dskip = draster - ((width + 7) >> 3);
412 byte *mask = gs_alloc_bytes(mem, draster * height,
413 "compress_alpha_bits");
414 const byte *sptr = data;
415 byte *dptr = mask;
416 uint h;
417
418 if (mask == 0)
419 return 0;
420 for (h = height; h; --h) {
421 byte sbit = 0x80;
422 byte d = 0;
423 byte dbit = 0x80;
424 uint w;
425
426 for (w = width; w; --w) {
427 if (*sptr & sbit)
428 d += dbit;
429 if (!(sbit >>= depth))
430 sbit = 0x80, sptr++;
431 if (!(dbit >>= 1)) {
432 *dptr++ = d;
433 dbit = 0x80, d = 0;
434 }
435 }
436 if (dbit != 0x80)
437 *dptr++ = d;
438 for (w = dskip; w != 0; --w)
439 *dptr++ = 0;
440 if (sbit != 0x80)
441 ++sptr;
442 sptr += sskip;
443 }
444 return mask;
445 }
446