17dd7cddfSDavid du Colombier /* Copyright (C) 1999, 2000 Aladdin Enterprises. All rights reserved.
27dd7cddfSDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
57dd7cddfSDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
17*593dc095SDavid du Colombier /* $Id: gschar.c,v 1.6 2002/06/16 05:48:55 lpd Exp $ */
187dd7cddfSDavid du Colombier /* Character writing "operators" for Ghostscript library */
197dd7cddfSDavid du Colombier #include "gx.h"
207dd7cddfSDavid du Colombier #include "gserrors.h"
217dd7cddfSDavid du Colombier #include "gsstruct.h"
227dd7cddfSDavid du Colombier #include "gsmatrix.h" /* for gscoord.h */
237dd7cddfSDavid du Colombier #include "gscoord.h" /* for gs_idtransform */
247dd7cddfSDavid du Colombier #include "gzstate.h"
257dd7cddfSDavid du Colombier #include "gxdevice.h"
267dd7cddfSDavid du Colombier #include "gxdevmem.h"
277dd7cddfSDavid du Colombier #include "gxchar.h"
287dd7cddfSDavid du Colombier #include "gxfont.h"
297dd7cddfSDavid du Colombier
307dd7cddfSDavid du Colombier /* Forward declarations */
31*593dc095SDavid du Colombier private int show_n_begin(gs_show_enum *penum, gs_state *pgs, int code,
32*593dc095SDavid du Colombier gs_text_enum_t *pte);
337dd7cddfSDavid du Colombier
347dd7cddfSDavid du Colombier /* Structure descriptors */
357dd7cddfSDavid du Colombier extern_st(st_gs_show_enum);
367dd7cddfSDavid du Colombier
377dd7cddfSDavid du Colombier /* ------ String writing operators ------ */
387dd7cddfSDavid du Colombier
397dd7cddfSDavid du Colombier /* Free the contents of a show enumerator. */
407dd7cddfSDavid du Colombier void
gs_show_enum_release(gs_show_enum * penum,gs_memory_t * emem)417dd7cddfSDavid du Colombier gs_show_enum_release(gs_show_enum * penum, gs_memory_t * emem)
427dd7cddfSDavid du Colombier {
437dd7cddfSDavid du Colombier if (penum->text.operation) /* otherwise, never initialized */
447dd7cddfSDavid du Colombier penum->procs->release((gs_text_enum_t *)penum, "gs_show_enum_release");
457dd7cddfSDavid du Colombier if (emem != 0)
467dd7cddfSDavid du Colombier gs_free_object(emem, penum, "gs_show_enum_release");
477dd7cddfSDavid du Colombier }
487dd7cddfSDavid du Colombier
497dd7cddfSDavid du Colombier /* show[_n] */
507dd7cddfSDavid du Colombier int
gs_show_n_init(gs_show_enum * penum,gs_state * pgs,const char * str,uint size)517dd7cddfSDavid du Colombier gs_show_n_init(gs_show_enum * penum, gs_state * pgs,
527dd7cddfSDavid du Colombier const char *str, uint size)
537dd7cddfSDavid du Colombier {
547dd7cddfSDavid du Colombier gs_text_enum_t *pte;
557dd7cddfSDavid du Colombier int code = gs_show_begin(pgs, (const byte *)str, size, pgs->memory, &pte);
567dd7cddfSDavid du Colombier
577dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
587dd7cddfSDavid du Colombier }
597dd7cddfSDavid du Colombier
607dd7cddfSDavid du Colombier /* ashow[_n] */
617dd7cddfSDavid du Colombier int
gs_ashow_n_init(gs_show_enum * penum,gs_state * pgs,floatp ax,floatp ay,const char * str,uint size)627dd7cddfSDavid du Colombier gs_ashow_n_init(gs_show_enum * penum, gs_state * pgs,
637dd7cddfSDavid du Colombier floatp ax, floatp ay, const char *str, uint size)
647dd7cddfSDavid du Colombier {
657dd7cddfSDavid du Colombier gs_text_enum_t *pte;
667dd7cddfSDavid du Colombier int code = gs_ashow_begin(pgs, ax, ay, (const byte *)str, size,
677dd7cddfSDavid du Colombier pgs->memory, &pte);
687dd7cddfSDavid du Colombier
697dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
707dd7cddfSDavid du Colombier }
717dd7cddfSDavid du Colombier
727dd7cddfSDavid du Colombier /* widthshow[_n] */
737dd7cddfSDavid du Colombier int
gs_widthshow_n_init(gs_show_enum * penum,gs_state * pgs,floatp cx,floatp cy,gs_char chr,const char * str,uint size)747dd7cddfSDavid du Colombier gs_widthshow_n_init(gs_show_enum * penum, gs_state * pgs,
757dd7cddfSDavid du Colombier floatp cx, floatp cy, gs_char chr,
767dd7cddfSDavid du Colombier const char *str, uint size)
777dd7cddfSDavid du Colombier {
787dd7cddfSDavid du Colombier gs_text_enum_t *pte;
797dd7cddfSDavid du Colombier int code = gs_widthshow_begin(pgs, cx, cy, chr, (const byte *)str, size,
807dd7cddfSDavid du Colombier pgs->memory, &pte);
817dd7cddfSDavid du Colombier
827dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
837dd7cddfSDavid du Colombier }
847dd7cddfSDavid du Colombier
857dd7cddfSDavid du Colombier /* awidthshow[_n] */
867dd7cddfSDavid du Colombier 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)877dd7cddfSDavid du Colombier gs_awidthshow_n_init(gs_show_enum * penum, gs_state * pgs,
887dd7cddfSDavid du Colombier floatp cx, floatp cy, gs_char chr, floatp ax, floatp ay,
897dd7cddfSDavid du Colombier const char *str, uint size)
907dd7cddfSDavid du Colombier {
917dd7cddfSDavid du Colombier gs_text_enum_t *pte;
927dd7cddfSDavid du Colombier int code = gs_awidthshow_begin(pgs, cx, cy, chr, ax, ay,
937dd7cddfSDavid du Colombier (const byte *)str, size, pgs->memory, &pte);
947dd7cddfSDavid du Colombier
957dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
967dd7cddfSDavid du Colombier }
977dd7cddfSDavid du Colombier
987dd7cddfSDavid du Colombier /* kshow[_n] */
997dd7cddfSDavid du Colombier int
gs_kshow_n_init(gs_show_enum * penum,gs_state * pgs,const char * str,uint size)1007dd7cddfSDavid du Colombier gs_kshow_n_init(gs_show_enum * penum,
1017dd7cddfSDavid du Colombier gs_state * pgs, const char *str, uint size)
1027dd7cddfSDavid du Colombier {
1037dd7cddfSDavid du Colombier gs_text_enum_t *pte;
1047dd7cddfSDavid du Colombier int code;
1057dd7cddfSDavid du Colombier
1067dd7cddfSDavid du Colombier switch (pgs->font->FontType) {
1077dd7cddfSDavid du Colombier case ft_composite:
1087dd7cddfSDavid du Colombier case ft_CID_encrypted:
1097dd7cddfSDavid du Colombier case ft_CID_user_defined:
1107dd7cddfSDavid du Colombier case ft_CID_TrueType:
1117dd7cddfSDavid du Colombier case ft_CID_bitmap:
1127dd7cddfSDavid du Colombier return_error(gs_error_invalidfont);
1137dd7cddfSDavid du Colombier default:
1147dd7cddfSDavid du Colombier break;
1157dd7cddfSDavid du Colombier }
1167dd7cddfSDavid du Colombier code = gs_kshow_begin(pgs, (const byte *)str, size, pgs->memory, &pte);
1177dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
1187dd7cddfSDavid du Colombier }
1197dd7cddfSDavid du Colombier
1207dd7cddfSDavid du Colombier /* xyshow[_n] */
1217dd7cddfSDavid du Colombier int
gs_xyshow_n_init(gs_show_enum * penum,gs_state * pgs,const char * str,uint size)1227dd7cddfSDavid du Colombier gs_xyshow_n_init(gs_show_enum * penum,
1237dd7cddfSDavid du Colombier gs_state * pgs, const char *str, uint size)
1247dd7cddfSDavid du Colombier {
1257dd7cddfSDavid du Colombier gs_text_enum_t *pte;
1267dd7cddfSDavid du Colombier int code = gs_xyshow_begin(pgs, (const byte *)str, size, NULL, NULL, 0,
1277dd7cddfSDavid du Colombier pgs->memory, &pte);
1287dd7cddfSDavid du Colombier
1297dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
1307dd7cddfSDavid du Colombier }
1317dd7cddfSDavid du Colombier
1327dd7cddfSDavid du Colombier /* glyphshow */
1337dd7cddfSDavid du Colombier int
gs_glyphshow_init(gs_show_enum * penum,gs_state * pgs,gs_glyph glyph)1347dd7cddfSDavid du Colombier gs_glyphshow_init(gs_show_enum * penum, gs_state * pgs, gs_glyph glyph)
1357dd7cddfSDavid du Colombier {
1367dd7cddfSDavid du Colombier gs_text_enum_t *pte;
1377dd7cddfSDavid du Colombier int code = gs_glyphshow_begin(pgs, glyph, pgs->memory, &pte);
1387dd7cddfSDavid du Colombier
1397dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
1407dd7cddfSDavid du Colombier }
1417dd7cddfSDavid du Colombier int
gs_glyphpath_init(gs_show_enum * penum,gs_state * pgs,gs_glyph glyph,bool stroke_path)1427dd7cddfSDavid du Colombier gs_glyphpath_init(gs_show_enum * penum, gs_state * pgs, gs_glyph glyph,
1437dd7cddfSDavid du Colombier bool stroke_path)
1447dd7cddfSDavid du Colombier {
1457dd7cddfSDavid du Colombier gs_text_enum_t *pte;
1467dd7cddfSDavid du Colombier int code = gs_glyphpath_begin(pgs, glyph, stroke_path, pgs->memory, &pte);
1477dd7cddfSDavid du Colombier
1487dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
1497dd7cddfSDavid du Colombier }
1507dd7cddfSDavid du Colombier int
gs_glyphwidth_init(gs_show_enum * penum,gs_state * pgs,gs_glyph glyph)1517dd7cddfSDavid du Colombier gs_glyphwidth_init(gs_show_enum * penum, gs_state * pgs, gs_glyph glyph)
1527dd7cddfSDavid du Colombier {
1537dd7cddfSDavid du Colombier gs_text_enum_t *pte;
1547dd7cddfSDavid du Colombier int code = gs_glyphwidth_begin(pgs, glyph, pgs->memory, &pte);
1557dd7cddfSDavid du Colombier
1567dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
1577dd7cddfSDavid du Colombier }
1587dd7cddfSDavid du Colombier
1597dd7cddfSDavid du Colombier /* ------ Related operators ------ */
1607dd7cddfSDavid du Colombier
1617dd7cddfSDavid du Colombier /* cshow[_n] */
1627dd7cddfSDavid du Colombier int
gs_cshow_n_init(gs_show_enum * penum,gs_state * pgs,const char * str,uint size)1637dd7cddfSDavid du Colombier gs_cshow_n_init(gs_show_enum * penum,
1647dd7cddfSDavid du Colombier gs_state * pgs, const char *str, uint size)
1657dd7cddfSDavid du Colombier {
1667dd7cddfSDavid du Colombier gs_text_enum_t *pte;
1677dd7cddfSDavid du Colombier int code = gs_cshow_begin(pgs, (const byte *)str, size, pgs->memory, &pte);
1687dd7cddfSDavid du Colombier
1697dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
1707dd7cddfSDavid du Colombier }
1717dd7cddfSDavid du Colombier
1727dd7cddfSDavid du Colombier /* stringwidth[_n] */
1737dd7cddfSDavid du Colombier int
gs_stringwidth_n_init(gs_show_enum * penum,gs_state * pgs,const char * str,uint size)1747dd7cddfSDavid du Colombier gs_stringwidth_n_init(gs_show_enum * penum, gs_state * pgs,
1757dd7cddfSDavid du Colombier const char *str, uint size)
1767dd7cddfSDavid du Colombier {
1777dd7cddfSDavid du Colombier gs_text_enum_t *pte;
1787dd7cddfSDavid du Colombier int code = gs_stringwidth_begin(pgs, (const byte *)str, size,
1797dd7cddfSDavid du Colombier pgs->memory, &pte);
1807dd7cddfSDavid du Colombier
1817dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
1827dd7cddfSDavid du Colombier }
1837dd7cddfSDavid du Colombier
1847dd7cddfSDavid du Colombier /* charpath[_n] */
1857dd7cddfSDavid du Colombier int
gs_charpath_n_init(gs_show_enum * penum,gs_state * pgs,const char * str,uint size,bool stroke_path)1867dd7cddfSDavid du Colombier gs_charpath_n_init(gs_show_enum * penum, gs_state * pgs,
1877dd7cddfSDavid du Colombier const char *str, uint size, bool stroke_path)
1887dd7cddfSDavid du Colombier {
1897dd7cddfSDavid du Colombier gs_text_enum_t *pte;
1907dd7cddfSDavid du Colombier int code = gs_charpath_begin(pgs, (const byte *)str, size, stroke_path,
1917dd7cddfSDavid du Colombier pgs->memory, &pte);
1927dd7cddfSDavid du Colombier
1937dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
1947dd7cddfSDavid du Colombier }
1957dd7cddfSDavid du Colombier
1967dd7cddfSDavid du Colombier /* charboxpath[_n] */
1977dd7cddfSDavid du Colombier int
gs_charboxpath_n_init(gs_show_enum * penum,gs_state * pgs,const char * str,uint size,bool use_boxes)1987dd7cddfSDavid du Colombier gs_charboxpath_n_init(gs_show_enum * penum, gs_state * pgs,
1997dd7cddfSDavid du Colombier const char *str, uint size, bool use_boxes)
2007dd7cddfSDavid du Colombier {
2017dd7cddfSDavid du Colombier gs_text_enum_t *pte;
2027dd7cddfSDavid du Colombier int code = gs_charboxpath_begin(pgs, (const byte *)str, size, use_boxes,
2037dd7cddfSDavid du Colombier pgs->memory, &pte);
2047dd7cddfSDavid du Colombier
2057dd7cddfSDavid du Colombier return show_n_begin(penum, pgs, code, pte);
2067dd7cddfSDavid du Colombier }
2077dd7cddfSDavid du Colombier
2087dd7cddfSDavid du Colombier /* ------ Width/cache operators ------ */
2097dd7cddfSDavid du Colombier
2107dd7cddfSDavid du Colombier /* setcachedevice */
2117dd7cddfSDavid du Colombier /* The elements of pw are: wx, wy, llx, lly, urx, ury. */
2127dd7cddfSDavid du Colombier /* Note that this returns 1 if we just set up the cache device. */
2137dd7cddfSDavid du Colombier int
gs_setcachedevice_double(gs_show_enum * penum,gs_state * pgs,const double * pw)2147dd7cddfSDavid du Colombier gs_setcachedevice_double(gs_show_enum *penum, gs_state *pgs, const double *pw)
2157dd7cddfSDavid du Colombier {
2167dd7cddfSDavid du Colombier if (penum->pgs != pgs)
2177dd7cddfSDavid du Colombier return_error(gs_error_rangecheck);
2187dd7cddfSDavid du Colombier return gs_text_setcachedevice((gs_text_enum_t *)penum, pw);
2197dd7cddfSDavid du Colombier }
2207dd7cddfSDavid du Colombier /* The _float procedure is strictly for backward compatibility. */
2217dd7cddfSDavid du Colombier int
gs_setcachedevice_float(gs_show_enum * penum,gs_state * pgs,const float * pw)2227dd7cddfSDavid du Colombier gs_setcachedevice_float(gs_show_enum * penum, gs_state * pgs, const float *pw)
2237dd7cddfSDavid du Colombier {
2247dd7cddfSDavid du Colombier double w[6];
2257dd7cddfSDavid du Colombier int i;
2267dd7cddfSDavid du Colombier
2277dd7cddfSDavid du Colombier for (i = 0; i < 6; ++i)
2287dd7cddfSDavid du Colombier w[i] = pw[i];
2297dd7cddfSDavid du Colombier return gs_setcachedevice_double(penum, pgs, w);
2307dd7cddfSDavid du Colombier }
2317dd7cddfSDavid du Colombier
2327dd7cddfSDavid du Colombier /* setcachedevice2 */
2337dd7cddfSDavid du Colombier /* The elements of pw2 are: w0x, w0y, llx, lly, urx, ury, w1x, w1y, vx, vy. */
2347dd7cddfSDavid du Colombier /* Note that this returns 1 if we just set up the cache device. */
2357dd7cddfSDavid du Colombier int
gs_setcachedevice2_double(gs_show_enum * penum,gs_state * pgs,const double * pw2)2367dd7cddfSDavid du Colombier gs_setcachedevice2_double(gs_show_enum * penum, gs_state * pgs,
2377dd7cddfSDavid du Colombier const double *pw2)
2387dd7cddfSDavid du Colombier {
2397dd7cddfSDavid du Colombier if (penum->pgs != pgs)
2407dd7cddfSDavid du Colombier return_error(gs_error_rangecheck);
2417dd7cddfSDavid du Colombier return gs_text_setcachedevice2((gs_text_enum_t *)penum, pw2);
2427dd7cddfSDavid du Colombier }
2437dd7cddfSDavid du Colombier /* The _float procedure is strictly for backward compatibility. */
2447dd7cddfSDavid du Colombier int
gs_setcachedevice2_float(gs_show_enum * penum,gs_state * pgs,const float * pw2)2457dd7cddfSDavid du Colombier gs_setcachedevice2_float(gs_show_enum * penum, gs_state * pgs, const float *pw2)
2467dd7cddfSDavid du Colombier {
2477dd7cddfSDavid du Colombier double w2[10];
2487dd7cddfSDavid du Colombier int i;
2497dd7cddfSDavid du Colombier
2507dd7cddfSDavid du Colombier for (i = 0; i < 10; ++i)
2517dd7cddfSDavid du Colombier w2[i] = pw2[i];
2527dd7cddfSDavid du Colombier return gs_setcachedevice2_double(penum, pgs, w2);
2537dd7cddfSDavid du Colombier }
2547dd7cddfSDavid du Colombier
2557dd7cddfSDavid du Colombier /* setcharwidth */
2567dd7cddfSDavid du Colombier /* Note that this returns 1 if the current show operation is */
2577dd7cddfSDavid du Colombier /* non-displaying (stringwidth or cshow). */
2587dd7cddfSDavid du Colombier int
gs_setcharwidth(gs_show_enum * penum,gs_state * pgs,floatp wx,floatp wy)2597dd7cddfSDavid du Colombier gs_setcharwidth(gs_show_enum * penum, gs_state * pgs,
2607dd7cddfSDavid du Colombier floatp wx, floatp wy)
2617dd7cddfSDavid du Colombier {
2627dd7cddfSDavid du Colombier double w[2];
2637dd7cddfSDavid du Colombier
2647dd7cddfSDavid du Colombier if (penum->pgs != pgs)
2657dd7cddfSDavid du Colombier return_error(gs_error_rangecheck);
2667dd7cddfSDavid du Colombier w[0] = wx, w[1] = wy;
2677dd7cddfSDavid du Colombier return gs_text_setcharwidth((gs_text_enum_t *)penum, w);
2687dd7cddfSDavid du Colombier }
2697dd7cddfSDavid du Colombier
2707dd7cddfSDavid du Colombier /* ------ Enumerator ------ */
2717dd7cddfSDavid du Colombier
2727dd7cddfSDavid du Colombier /* Do the next step of a show (or stringwidth) operation */
2737dd7cddfSDavid du Colombier int
gs_show_next(gs_show_enum * penum)2747dd7cddfSDavid du Colombier gs_show_next(gs_show_enum * penum)
2757dd7cddfSDavid du Colombier {
2767dd7cddfSDavid du Colombier return gs_text_process((gs_text_enum_t *)penum);
2777dd7cddfSDavid du Colombier }
2787dd7cddfSDavid du Colombier
2797dd7cddfSDavid du Colombier /*
2807dd7cddfSDavid du Colombier * Return true if we only need the width from the rasterizer
2817dd7cddfSDavid du Colombier * and can short-circuit the full rendering of the character,
2827dd7cddfSDavid du Colombier * false if we need the actual character bits.
2837dd7cddfSDavid du Colombier */
2847dd7cddfSDavid du Colombier bool
gs_show_width_only(const gs_show_enum * penum)2857dd7cddfSDavid du Colombier gs_show_width_only(const gs_show_enum * penum)
2867dd7cddfSDavid du Colombier {
2877dd7cddfSDavid du Colombier return gs_text_is_width_only((const gs_text_enum_t *)penum);
2887dd7cddfSDavid du Colombier }
2897dd7cddfSDavid du Colombier
2907dd7cddfSDavid du Colombier /* ------ Accessors ------ */
2917dd7cddfSDavid du Colombier
2927dd7cddfSDavid du Colombier /* Return the current character for rendering. */
2937dd7cddfSDavid du Colombier gs_char
gs_show_current_char(const gs_show_enum * penum)2947dd7cddfSDavid du Colombier gs_show_current_char(const gs_show_enum * penum)
2957dd7cddfSDavid du Colombier {
2967dd7cddfSDavid du Colombier return gs_text_current_char((const gs_text_enum_t *)penum);
2977dd7cddfSDavid du Colombier }
2987dd7cddfSDavid du Colombier
2997dd7cddfSDavid du Colombier /* Return the current glyph for rendering. */
3007dd7cddfSDavid du Colombier gs_glyph
gs_show_current_glyph(const gs_show_enum * penum)3017dd7cddfSDavid du Colombier gs_show_current_glyph(const gs_show_enum * penum)
3027dd7cddfSDavid du Colombier {
3037dd7cddfSDavid du Colombier return gs_text_current_glyph((const gs_text_enum_t *)penum);
3047dd7cddfSDavid du Colombier }
3057dd7cddfSDavid du Colombier
3067dd7cddfSDavid du Colombier /* Return the width of the just-enumerated character (for cshow). */
3077dd7cddfSDavid du Colombier int
gs_show_current_width(const gs_show_enum * penum,gs_point * ppt)3087dd7cddfSDavid du Colombier gs_show_current_width(const gs_show_enum * penum, gs_point * ppt)
3097dd7cddfSDavid du Colombier {
3107dd7cddfSDavid du Colombier return gs_text_current_width((const gs_text_enum_t *)penum, ppt);
3117dd7cddfSDavid du Colombier }
3127dd7cddfSDavid du Colombier
3137dd7cddfSDavid du Colombier /* Return the just-displayed character for kerning. */
3147dd7cddfSDavid du Colombier gs_char
gs_kshow_previous_char(const gs_show_enum * penum)3157dd7cddfSDavid du Colombier gs_kshow_previous_char(const gs_show_enum * penum)
3167dd7cddfSDavid du Colombier {
3177dd7cddfSDavid du Colombier return gs_text_current_char((const gs_text_enum_t *)penum);
3187dd7cddfSDavid du Colombier }
3197dd7cddfSDavid du Colombier
3207dd7cddfSDavid du Colombier /* Return the about-to-be-displayed character for kerning. */
3217dd7cddfSDavid du Colombier gs_char
gs_kshow_next_char(const gs_show_enum * penum)3227dd7cddfSDavid du Colombier gs_kshow_next_char(const gs_show_enum * penum)
3237dd7cddfSDavid du Colombier {
3247dd7cddfSDavid du Colombier return penum->text.data.bytes[penum->index];
3257dd7cddfSDavid du Colombier }
3267dd7cddfSDavid du Colombier
3277dd7cddfSDavid du Colombier /* Return the accumulated width for stringwidth. */
3287dd7cddfSDavid du Colombier void
gs_show_width(const gs_show_enum * penum,gs_point * ppt)3297dd7cddfSDavid du Colombier gs_show_width(const gs_show_enum * penum, gs_point * ppt)
3307dd7cddfSDavid du Colombier {
3317dd7cddfSDavid du Colombier gs_text_total_width((const gs_text_enum_t *)penum, ppt);
3327dd7cddfSDavid du Colombier }
3337dd7cddfSDavid du Colombier
3347dd7cddfSDavid du Colombier /* ------ Internal routines ------ */
3357dd7cddfSDavid du Colombier
3367dd7cddfSDavid du Colombier /*
3377dd7cddfSDavid du Colombier * Force the enumerator to be a gs_show_enum *, which the current
3387dd7cddfSDavid du Colombier * implementation code requires.
3397dd7cddfSDavid du Colombier */
3407dd7cddfSDavid du Colombier private int
show_n_begin(gs_show_enum * penum,gs_state * pgs,int code,gs_text_enum_t * pte)3417dd7cddfSDavid du Colombier show_n_begin(gs_show_enum *penum, gs_state *pgs, int code, gs_text_enum_t *pte)
3427dd7cddfSDavid du Colombier {
3437dd7cddfSDavid du Colombier if (code < 0)
3447dd7cddfSDavid du Colombier return code;
3457dd7cddfSDavid du Colombier if (gs_object_type(pgs->memory, pte) != &st_gs_show_enum) {
3467dd7cddfSDavid du Colombier /* Use the default implementation. */
3477dd7cddfSDavid du Colombier gx_device *dev = pgs->device;
3487dd7cddfSDavid du Colombier gs_text_params_t text;
3497dd7cddfSDavid du Colombier gs_memory_t *mem = pte->memory;
3507dd7cddfSDavid du Colombier dev_proc_text_begin((*text_begin)) = dev_proc(dev, text_begin);
3517dd7cddfSDavid du Colombier
3527dd7cddfSDavid du Colombier text = pte->text;
3537dd7cddfSDavid du Colombier gs_text_release(pte, "show_n_begin");
3547dd7cddfSDavid du Colombier /* Temporarily reset the text_begin procedure to the default. */
3557dd7cddfSDavid du Colombier set_dev_proc(dev, text_begin, gx_default_text_begin);
3567dd7cddfSDavid du Colombier code = gs_text_begin(pgs, &text, mem, &pte);
3577dd7cddfSDavid du Colombier set_dev_proc(dev, text_begin, text_begin);
3587dd7cddfSDavid du Colombier if (code < 0)
3597dd7cddfSDavid du Colombier return code;
3607dd7cddfSDavid du Colombier }
3617dd7cddfSDavid du Colombier /* Now we know pte points to a gs_show_enum. */
3627dd7cddfSDavid du Colombier *penum = *(gs_show_enum *)pte;
3637dd7cddfSDavid du Colombier gs_free_object(pgs->memory, pte, "show_n_begin");
3647dd7cddfSDavid du Colombier return code;
3657dd7cddfSDavid du Colombier }
366