1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
|
/* Copyright (C) 2001-2006 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
implied.
This software is distributed under license and may not be copied, modified
or distributed except as expressly authorized under the terms of that
license. Refer to licensing information at http://www.artifex.com/
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
*/
/* $Id: gschar.c 8250 2007-09-25 13:31:24Z giles $ */
/* Character writing "operators" for Ghostscript library */
#include "gx.h"
#include "gserrors.h"
#include "gsstruct.h"
#include "gsmatrix.h" /* for gscoord.h */
#include "gscoord.h" /* for gs_idtransform */
#include "gzstate.h"
#include "gxdevice.h"
#include "gxdevmem.h"
#include "gxchar.h"
#include "gxfont.h"
/* Forward declarations */
static int show_n_begin(gs_show_enum *penum, gs_state *pgs, int code,
gs_text_enum_t *pte);
/* Structure descriptors */
extern_st(st_gs_show_enum);
/* ------ String writing operators ------ */
/* Free the contents of a show enumerator. */
void
gs_show_enum_release(gs_show_enum * penum, gs_memory_t * emem)
{
if (penum->text.operation) /* otherwise, never initialized */
penum->procs->release((gs_text_enum_t *)penum, "gs_show_enum_release");
if (emem != 0)
gs_free_object(emem, penum, "gs_show_enum_release");
}
/* show[_n] */
int
gs_show_n_init(gs_show_enum * penum, gs_state * pgs,
const char *str, uint size)
{
gs_text_enum_t *pte;
int code = gs_show_begin(pgs, (const byte *)str, size, pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* ashow[_n] */
int
gs_ashow_n_init(gs_show_enum * penum, gs_state * pgs,
floatp ax, floatp ay, const char *str, uint size)
{
gs_text_enum_t *pte;
int code = gs_ashow_begin(pgs, ax, ay, (const byte *)str, size,
pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* widthshow[_n] */
int
gs_widthshow_n_init(gs_show_enum * penum, gs_state * pgs,
floatp cx, floatp cy, gs_char chr,
const char *str, uint size)
{
gs_text_enum_t *pte;
int code = gs_widthshow_begin(pgs, cx, cy, chr, (const byte *)str, size,
pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* awidthshow[_n] */
int
gs_awidthshow_n_init(gs_show_enum * penum, gs_state * pgs,
floatp cx, floatp cy, gs_char chr, floatp ax, floatp ay,
const char *str, uint size)
{
gs_text_enum_t *pte;
int code = gs_awidthshow_begin(pgs, cx, cy, chr, ax, ay,
(const byte *)str, size, pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* kshow[_n] */
int
gs_kshow_n_init(gs_show_enum * penum,
gs_state * pgs, const char *str, uint size)
{
gs_text_enum_t *pte;
int code;
switch (pgs->font->FontType) {
case ft_composite:
case ft_CID_encrypted:
case ft_CID_user_defined:
case ft_CID_TrueType:
case ft_CID_bitmap:
return_error(gs_error_invalidfont);
default:
break;
}
code = gs_kshow_begin(pgs, (const byte *)str, size, pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* xyshow[_n] */
int
gs_xyshow_n_init(gs_show_enum * penum,
gs_state * pgs, const char *str, uint size)
{
gs_text_enum_t *pte;
int code = gs_xyshow_begin(pgs, (const byte *)str, size, NULL, NULL, 0,
pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* glyphshow */
int
gs_glyphshow_init(gs_show_enum * penum, gs_state * pgs, gs_glyph glyph)
{
gs_text_enum_t *pte;
int code = gs_glyphshow_begin(pgs, glyph, pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
int
gs_glyphpath_init(gs_show_enum * penum, gs_state * pgs, gs_glyph glyph,
bool stroke_path)
{
gs_text_enum_t *pte;
int code = gs_glyphpath_begin(pgs, glyph, stroke_path, pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
int
gs_glyphwidth_init(gs_show_enum * penum, gs_state * pgs, gs_glyph glyph)
{
gs_text_enum_t *pte;
int code = gs_glyphwidth_begin(pgs, glyph, pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* ------ Related operators ------ */
/* cshow[_n] */
int
gs_cshow_n_init(gs_show_enum * penum,
gs_state * pgs, const char *str, uint size)
{
gs_text_enum_t *pte;
int code = gs_cshow_begin(pgs, (const byte *)str, size, pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* stringwidth[_n] */
int
gs_stringwidth_n_init(gs_show_enum * penum, gs_state * pgs,
const char *str, uint size)
{
gs_text_enum_t *pte;
int code = gs_stringwidth_begin(pgs, (const byte *)str, size,
pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* charpath[_n] */
int
gs_charpath_n_init(gs_show_enum * penum, gs_state * pgs,
const char *str, uint size, bool stroke_path)
{
gs_text_enum_t *pte;
int code = gs_charpath_begin(pgs, (const byte *)str, size, stroke_path,
pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* charboxpath[_n] */
int
gs_charboxpath_n_init(gs_show_enum * penum, gs_state * pgs,
const char *str, uint size, bool use_boxes)
{
gs_text_enum_t *pte;
int code = gs_charboxpath_begin(pgs, (const byte *)str, size, use_boxes,
pgs->memory, &pte);
return show_n_begin(penum, pgs, code, pte);
}
/* ------ Width/cache operators ------ */
/* setcachedevice */
/* The elements of pw are: wx, wy, llx, lly, urx, ury. */
/* Note that this returns 1 if we just set up the cache device. */
int
gs_setcachedevice_double(gs_show_enum *penum, gs_state *pgs, const double *pw)
{
if (penum->pgs != pgs)
return_error(gs_error_rangecheck);
return gs_text_setcachedevice((gs_text_enum_t *)penum, pw);
}
/* The _float procedure is strictly for backward compatibility. */
int
gs_setcachedevice_float(gs_show_enum * penum, gs_state * pgs, const float *pw)
{
double w[6];
int i;
for (i = 0; i < 6; ++i)
w[i] = pw[i];
return gs_setcachedevice_double(penum, pgs, w);
}
/* setcachedevice2 */
/* The elements of pw2 are: w0x, w0y, llx, lly, urx, ury, w1x, w1y, vx, vy. */
/* Note that this returns 1 if we just set up the cache device. */
int
gs_setcachedevice2_double(gs_show_enum * penum, gs_state * pgs,
const double *pw2)
{
if (penum->pgs != pgs)
return_error(gs_error_rangecheck);
return gs_text_setcachedevice2((gs_text_enum_t *)penum, pw2);
}
/* The _float procedure is strictly for backward compatibility. */
int
gs_setcachedevice2_float(gs_show_enum * penum, gs_state * pgs, const float *pw2)
{
double w2[10];
int i;
for (i = 0; i < 10; ++i)
w2[i] = pw2[i];
return gs_setcachedevice2_double(penum, pgs, w2);
}
/* setcharwidth */
/* Note that this returns 1 if the current show operation is */
/* non-displaying (stringwidth or cshow). */
int
gs_setcharwidth(gs_show_enum * penum, gs_state * pgs,
floatp wx, floatp wy)
{
double w[2];
if (penum->pgs != pgs)
return_error(gs_error_rangecheck);
w[0] = wx, w[1] = wy;
return gs_text_setcharwidth((gs_text_enum_t *)penum, w);
}
/* ------ Enumerator ------ */
/* Do the next step of a show (or stringwidth) operation */
int
gs_show_next(gs_show_enum * penum)
{
return gs_text_process((gs_text_enum_t *)penum);
}
/*
* Return true if we only need the width from the rasterizer
* and can short-circuit the full rendering of the character,
* false if we need the actual character bits.
*/
bool
gs_show_width_only(const gs_show_enum * penum)
{
return gs_text_is_width_only((const gs_text_enum_t *)penum);
}
/* ------ Accessors ------ */
/* Return the current character for rendering. */
gs_char
gs_show_current_char(const gs_show_enum * penum)
{
return gs_text_current_char((const gs_text_enum_t *)penum);
}
/* Return the current glyph for rendering. */
gs_glyph
gs_show_current_glyph(const gs_show_enum * penum)
{
return gs_text_current_glyph((const gs_text_enum_t *)penum);
}
/* Return the width of the just-enumerated character (for cshow). */
int
gs_show_current_width(const gs_show_enum * penum, gs_point * ppt)
{
return gs_text_current_width((const gs_text_enum_t *)penum, ppt);
}
/* Return the just-displayed character for kerning. */
gs_char
gs_kshow_previous_char(const gs_show_enum * penum)
{
return gs_text_current_char((const gs_text_enum_t *)penum);
}
/* Return the about-to-be-displayed character for kerning. */
gs_char
gs_kshow_next_char(const gs_show_enum * penum)
{
return penum->text.data.bytes[penum->index];
}
/* Return the accumulated width for stringwidth. */
void
gs_show_width(const gs_show_enum * penum, gs_point * ppt)
{
gs_text_total_width((const gs_text_enum_t *)penum, ppt);
}
/* ------ Internal routines ------ */
/*
* Force the enumerator to be a gs_show_enum *, which the current
* implementation code requires.
*/
static int
show_n_begin(gs_show_enum *penum, gs_state *pgs, int code, gs_text_enum_t *pte)
{
if (code < 0)
return code;
if (gs_object_type(pgs->memory, pte) != &st_gs_show_enum) {
/* Use the default implementation. */
gx_device *dev = pgs->device;
gs_text_params_t text;
gs_memory_t *mem = pte->memory;
dev_proc_text_begin((*text_begin)) = dev_proc(dev, text_begin);
text = pte->text;
gs_text_release(pte, "show_n_begin");
/* Temporarily reset the text_begin procedure to the default. */
set_dev_proc(dev, text_begin, gx_default_text_begin);
code = gs_text_begin(pgs, &text, mem, &pte);
set_dev_proc(dev, text_begin, text_begin);
if (code < 0)
return code;
}
/* Now we know pte points to a gs_show_enum. */
*penum = *(gs_show_enum *)pte;
gs_free_object(pgs->memory, pte, "show_n_begin");
return code;
}
|