/* Copyright (C) 1998, 2000 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: gstext.h,v 1.3.6.1.2.1 2003/01/17 00:49:03 giles Exp $ */ /* Driver interface for text */ #ifndef gstext_INCLUDED # define gstext_INCLUDED #include "gsccode.h" #include "gscpm.h" /* * Note that text display must return information to the generic code: * If TEXT_RETURN_WIDTH or TEXT_DO_CHARWIDTH, the string escapement * (a.k.a. "width"); * If TEXT_DO_*_CHARPATH, the entire character description; * If TEXT_DO_*_CHARBOXPATH, the character bounding box. */ /* * Define the set of possible text operations. While we define this as * a bit mask for convenience in testing, only certain combinations are * meaningful. Specifically, the following are errors: * - No FROM or DO. * - More than one FROM or DO. * - FROM_SINGLE with size != 1. * - Both ADD_TO and REPLACE. */ #define TEXT_HAS_MORE_THAN_ONE_(op, any)\ ( ((op) & any) & (((op) & any) - 1) ) #define TEXT_OPERATION_IS_INVALID(op)\ (!((op) & TEXT_FROM_ANY) ||\ !((op) & TEXT_DO_ANY) ||\ TEXT_HAS_MORE_THAN_ONE_(op, TEXT_FROM_ANY) ||\ TEXT_HAS_MORE_THAN_ONE_(op, TEXT_DO_ANY) ||\ (((op) & TEXT_ADD_ANY) && ((op) & TEXT_REPLACE_WIDTHS))\ ) #define TEXT_PARAMS_ARE_INVALID(params)\ (TEXT_OPERATION_IS_INVALID((params)->operation) ||\ ( ((params)->operation & TEXT_FROM_ANY_SINGLE) && ((params)->size != 1) )\ ) /* Define the representation of the text itself. */ #define TEXT_FROM_STRING 0x00001 #define TEXT_FROM_BYTES 0x00002 #define TEXT_FROM_CHARS 0x00004 #define TEXT_FROM_GLYPHS 0x00008 #define TEXT_FROM_SINGLE_CHAR 0x00010 #define TEXT_FROM_SINGLE_GLYPH 0x00020 #define TEXT_FROM_ANY_SINGLE /* only for testing and masking */\ (TEXT_FROM_SINGLE_CHAR | TEXT_FROM_SINGLE_GLYPH) #define TEXT_FROM_ANY /* only for testing and masking */\ (TEXT_FROM_STRING | TEXT_FROM_BYTES | TEXT_FROM_CHARS | TEXT_FROM_GLYPHS |\ TEXT_FROM_ANY_SINGLE) /* Define how to compute escapements. */ #define TEXT_ADD_TO_ALL_WIDTHS 0x00040 #define TEXT_ADD_TO_SPACE_WIDTH 0x00080 #define TEXT_ADD_ANY /* only for testing and masking */\ (TEXT_ADD_TO_ALL_WIDTHS | TEXT_ADD_TO_SPACE_WIDTH) #define TEXT_REPLACE_WIDTHS 0x00100 /* Define what result should be produced. */ #define TEXT_DO_NONE 0x00200 /* stringwidth or cshow only */ #define TEXT_DO_DRAW 0x00400 #define TEXT_DO_CHARWIDTH 0x00800 /* rmoveto by width */ #define TEXT_DO_FALSE_CHARPATH 0x01000 #define TEXT_DO_TRUE_CHARPATH 0x02000 #define TEXT_DO_FALSE_CHARBOXPATH 0x04000 #define TEXT_DO_TRUE_CHARBOXPATH 0x08000 #define TEXT_DO_ANY_CHARPATH /* only for testing and masking */\ (TEXT_DO_CHARWIDTH | TEXT_DO_FALSE_CHARPATH | TEXT_DO_TRUE_CHARPATH |\ TEXT_DO_FALSE_CHARBOXPATH | TEXT_DO_TRUE_CHARBOXPATH) #define TEXT_DO_ANY /* only for testing and masking */\ (TEXT_DO_NONE | TEXT_DO_DRAW | TEXT_DO_ANY_CHARPATH) /* Define whether the client intervenes between characters. */ #define TEXT_INTERVENE 0x10000 /* Define whether to return the width. */ #define TEXT_RETURN_WIDTH 0x20000 /* * Define the structure of parameters passed in for text display. * Note that the implementation does not modify any of these; the client * must not modify them after initialization. */ typedef struct gs_text_params_s { /* The client must set the following in all cases. */ uint operation; /* TEXT_xxx mask */ union sd_ { const byte *bytes; /* FROM_STRING, FROM_BYTES */ const gs_char *chars; /* FROM_CHARS */ const gs_glyph *glyphs; /* FROM_GLYPHS */ gs_char d_char; /* FROM_SINGLE_CHAR */ gs_glyph d_glyph; /* FROM_SINGLE_GLYPH */ } data; uint size; /* number of data elements, */ /* must be 1 if FROM_SINGLE */ /* The following are used only in the indicated cases. */ gs_point delta_all; /* ADD_TO_ALL_WIDTHS */ gs_point delta_space; /* ADD_TO_SPACE_WIDTH */ union s_ { gs_char s_char; /* ADD_TO_SPACE_WIDTH & !FROM_GLYPHS */ gs_glyph s_glyph; /* ADD_TO_SPACE_WIDTH & FROM_GLYPHS */ } space; /* If x_widths == y_widths, widths are taken in pairs. */ /* Either one may be NULL, meaning widths = 0. */ const float *x_widths; /* REPLACE_WIDTHS */ const float *y_widths; /* REPLACE_WIDTHS */ uint widths_size; /****** PROBABLY NOT NEEDED ******/ } gs_text_params_t; #define st_gs_text_params_max_ptrs 3 /*extern_st(st_gs_text_params); */ #define public_st_gs_text_params() /* in gstext.c */\ gs_public_st_composite(st_gs_text_params, gs_text_params_t,\ "gs_text_params", text_params_enum_ptrs, text_params_reloc_ptrs) /* Assuming REPLACE_WIDTHS is set, return the width of the i'th character. */ int gs_text_replaced_width(P3(const gs_text_params_t *text, uint index, gs_point *pwidth)); /* * Define the abstract type for the structure that tracks the state of text * processing. */ #ifndef gs_text_enum_DEFINED # define gs_text_enum_DEFINED typedef struct gs_text_enum_s gs_text_enum_t; #endif /* Abstract types */ #ifndef gx_device_DEFINED # define gx_device_DEFINED typedef struct gx_device_s gx_device; #endif #ifndef gs_imager_state_DEFINED # define gs_imager_state_DEFINED typedef struct gs_imager_state_s gs_imager_state; #endif #ifndef gx_device_color_DEFINED # define gx_device_color_DEFINED typedef struct gx_device_color_s gx_device_color; #endif #ifndef gs_font_DEFINED # define gs_font_DEFINED typedef struct gs_font_s gs_font; #endif #ifndef gx_path_DEFINED # define gx_path_DEFINED typedef struct gx_path_s gx_path; #endif #ifndef gx_clip_path_DEFINED # define gx_clip_path_DEFINED typedef struct gx_clip_path_s gx_clip_path; #endif /* * Define the driver procedure for text. This procedure must allocate * the enumerator (see gxtext.h) and initialize the procs and rc members. */ #define dev_t_proc_text_begin(proc, dev_t)\ int proc(P9(dev_t *dev,\ gs_imager_state *pis,\ const gs_text_params_t *text,\ gs_font *font,\ gx_path *path, /* unless DO_NONE */\ const gx_device_color *pdcolor, /* if DO_DRAW */\ const gx_clip_path *pcpath, /* if DO_DRAW */\ gs_memory_t *memory,\ gs_text_enum_t **ppte)) #define dev_proc_text_begin(proc)\ dev_t_proc_text_begin(proc, gx_device) /* * Begin processing text. This calls the device procedure, and also * initializes the common parts of the enumerator. */ dev_proc_text_begin(gx_device_text_begin); /* Begin processing text with a graphics state. */ #ifndef gs_state_DEFINED # define gs_state_DEFINED typedef struct gs_state_s gs_state; #endif int gs_text_begin(P4(gs_state * pgs, const gs_text_params_t * text, gs_memory_t * mem, gs_text_enum_t ** ppenum)); /* Begin the PostScript-equivalent text operators. */ int gs_show_begin(P5(gs_state *, const byte *, uint, gs_memory_t *, gs_text_enum_t **)), gs_ashow_begin(P7(gs_state *, floatp, floatp, const byte *, uint, gs_memory_t *, gs_text_enum_t **)), gs_widthshow_begin(P8(gs_state *, floatp, floatp, gs_char, const byte *, uint, gs_memory_t *, gs_text_enum_t **)), gs_awidthshow_begin(P10(gs_state *, floatp, floatp, gs_char, floatp, floatp, const byte *, uint, gs_memory_t *, gs_text_enum_t **)), gs_kshow_begin(P5(gs_state *, const byte *, uint, gs_memory_t *, gs_text_enum_t **)), gs_xyshow_begin(P8(gs_state *, const byte *, uint, const float *, const float *, uint, gs_memory_t *, gs_text_enum_t **)), gs_glyphshow_begin(P4(gs_state *, gs_glyph, gs_memory_t *, gs_text_enum_t **)), gs_cshow_begin(P5(gs_state *, const byte *, uint, gs_memory_t *, gs_text_enum_t **)), gs_stringwidth_begin(P5(gs_state *, const byte *, uint, gs_memory_t *, gs_text_enum_t **)), gs_charpath_begin(P6(gs_state *, const byte *, uint, bool, gs_memory_t *, gs_text_enum_t **)), gs_glyphpath_begin(P5(gs_state *, gs_glyph, bool, gs_memory_t *, gs_text_enum_t **)), gs_glyphwidth_begin(P4(gs_state *, gs_glyph, gs_memory_t *, gs_text_enum_t **)), gs_charboxpath_begin(P6(gs_state *, const byte *, uint, bool, gs_memory_t *, gs_text_enum_t **)); /* * Restart text processing with new parameters. */ int gs_text_restart(P2(gs_text_enum_t *pte, const gs_text_params_t *text)); /* * Resync text processing with new parameters and string position. */ int gs_text_resync(P2(gs_text_enum_t *pte, const gs_text_enum_t *pfrom)); /* * Define the possible return values from gs_text_process. The client * should call text_process until it returns 0 (successful completion) or a * negative (error) value. */ /* * The client must render a character: obtain the code from * gs_text_current_char/glyph, do whatever is necessary, and then * call gs_text_process again. */ #define TEXT_PROCESS_RENDER 1 /* * The client has asked to intervene between characters. * Obtain the current and next codes from gs_text_current_char/glyph * and gs_text_next_char, do whatever is necessary, and then * call gs_text_process again. */ #define TEXT_PROCESS_INTERVENE 2 /* Process text after 'begin'. */ int gs_text_process(P1(gs_text_enum_t *pte)); /* Access elements of the enumerator. */ gs_font *gs_text_current_font(P1(const gs_text_enum_t *pte)); gs_char gs_text_current_char(P1(const gs_text_enum_t *pte)); gs_char gs_text_next_char(P1(const gs_text_enum_t *pte)); gs_glyph gs_text_current_glyph(P1(const gs_text_enum_t *pte)); int gs_text_total_width(P2(const gs_text_enum_t *pte, gs_point *pwidth)); /* * After the implementation returned TEXT_PROCESS_RENDER, determine * whether it needs the entire character description, or only the width * (escapement). */ bool gs_text_is_width_only(P1(const gs_text_enum_t *pte)); /* * Return the width of the current character (in user space coordinates). */ int gs_text_current_width(P2(const gs_text_enum_t *pte, gs_point *pwidth)); /* * Set text metrics and optionally enable caching. Return 1 iff the * cache device was just installed. */ typedef enum { TEXT_SET_CHAR_WIDTH, /* wx wy */ TEXT_SET_CACHE_DEVICE, /* wx wy llx lly urx ury */ TEXT_SET_CACHE_DEVICE2 /* w0x w0y llx lly urx ury w1x w1y vx vy */ } gs_text_cache_control_t; int gs_text_set_cache(P3(gs_text_enum_t *pte, const double *values, gs_text_cache_control_t control)), gs_text_setcharwidth(P2(gs_text_enum_t *pte, const double wxy[2])), gs_text_setcachedevice(P2(gs_text_enum_t *pte, const double wbox[6])), gs_text_setcachedevice2(P2(gs_text_enum_t *pte, const double wbox2[10])); /* Retry processing of the last character. */ int gs_text_retry(P1(gs_text_enum_t *pte)); /* Release the text processing structures. */ void gs_text_release(P2(gs_text_enum_t *pte, client_name_t cname)); #endif /* gstext_INCLUDED */