home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
g
/
gs241j11.zip
/
ZCOMP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-01
|
25KB
|
1,140 lines
/*
* Composite String Decoding Utility
*
* Copyright (C) 1991,1992 Norio Katayama.
* Aug.17, 1991 Programmed by N.Katayama (katayama@nacsis.ac.jp)
* May. 2, 1992 Revised by N.Katayama
*/
#include "memory_.h"
#include "ghost.h"
#include "errors.h"
#include "oper.h"
#include "gxfixed.h" /* for gxmatrix.h */
#include "gxmatrix.h"
#include "gschar.h"
#include "gxdevice.h" /* for gxfont.h */
#include "gxfont.h"
#include "gspath.h"
#include "gzstate.h"
#include "alloc.h"
#include "dict.h"
#include "font.h"
#include "iutil.h"
#include "name.h"
#include "estack.h"
#include "state.h"
#include "store.h"
#undef DEBUG
#define es_comp 999 /* probable to conflict with other definition */
#define FontStackDepth 5
/* Imported functions */
extern int zshow(P1(os_ptr)), zashow(P1(os_ptr));
extern int zwidthshow(P1(os_ptr)), zawidthshow(P1(os_ptr));
extern int zcharpath(P1(os_ptr)), zstringwidth(P1(os_ptr));
extern int zload(P1(os_ptr));
extern int add_FID(P2(ref *, gs_font *));
/* Imported varables */
extern gs_font_dir *ifont_dir;
extern ref name_FID;
extern ref name_FontMatrix;
/* Font context */
struct context {
/* Font stack */
ref dictstack[FontStackDepth];
gs_font *fontstack[FontStackDepth];
int fdepth;
/* Mapping information */
int font_no[FontStackDepth];
int modal[FontStackDepth];
/* String */
byte *buffer;
int buffer_size;
byte *str;
int len;
byte code; /* result of font mapping decoder */
/* Procedures */
int (*base_proc)(P2(os_ptr, struct context *));
int (*final_proc)(P2(os_ptr, struct context *));
/* Procedure tags */
int in_cshow; /* true if in cshow */
int index; /* index of op_def_table */
float axy[2]; /* for ashow and awidthshow */
float cxy[2]; /* for widthshow and awidthshow */
char_code wschar;
float wxy[2]; /* for stringwidth */
int charpath_flag; /* for charpath */
ref cshow_proc; /* for cshow */
};
typedef int (*comp_proc)(P2(os_ptr, struct context *));
/* Forward declarations */
private int base_show(P2(os_ptr, struct context *));
private int base_ashow(P2(os_ptr, struct context *));
private int base_widthshow(P2(os_ptr, struct context *));
private int base_awidthshow(P2(os_ptr, struct context *));
private int base_charpath(P2(os_ptr, struct context *));
private int base_stringwidth(P2(os_ptr, struct context *));
private int final_stringwidth(P2(os_ptr, struct context *));
private int base_cshow(P2(os_ptr, struct context *));
private int setup_context(P4(os_ptr, comp_proc, comp_proc, struct context **));
private int free_context(P1(struct context *));
private int comp_continue(P1(os_ptr));
private int FMapType2(P1(struct context *));
private int FMapType3(P1(struct context *));
private int FMapType4(P1(struct context *));
private int FMapType5(P1(struct context *));
private int FMapType6(P1(struct context *));
private int FMapType7(P1(struct context *));
private int FMapType8(P1(struct context *));
private int push_font(P3(struct context *, int, int));
private int pop_font(P1(struct context *));
private int getwschar(P1(struct context *));
private int comp_setfont(P1(struct context *));
private int i_zshow0;
private int i_zashow0;
private int i_zwidthshow0;
private int i_zawidthshow0;
private int i_zcharpath0;
private int i_zstringwidth0;
private int i_zcshow0;
#define check_currentpoint(pgs) \
{ gs_point pt; if((code = gs_currentpoint(pgs, &pt)) < 0) return code; }
/*
* show0
*/
int
zshow0(register os_ptr op)
{
int code;
struct context *context;
if((code = setup_context(op, base_show, NULL, &context)) < 0)
return code;
check_currentpoint(igs);
pop(1);
op --;
context->index = i_zshow0;
return comp_continue(op);
}
/*
* ashow0
*/
int
zashow0(register os_ptr op)
{
int code;
struct context *context;
if((code = setup_context(op, base_ashow, NULL, &context)) < 0)
return code;
if((code = num_params(op - 1, 2, context->axy)) < 0)
return code;
check_currentpoint(igs);
pop(3);
op -= 3;
context->index = i_zashow0;
return comp_continue(op);
}
/*
* widthshow()
*/
int
zwidthshow0(register os_ptr op)
{
int code;
struct context *context;
if((code = setup_context(op, base_widthshow, NULL, &context)) < 0)
return code;
check_type(op[-1], t_integer);
context->wschar = (char_code)op[-1].value.intval;
if((code = num_params(op - 2, 2, context->cxy)) < 0)
return code;
check_currentpoint(igs);
pop(4);
op -= 4;
context->index = i_zwidthshow0;
return comp_continue(op);
}
/*
* awidthshow()
*/
int
zawidthshow0(register os_ptr op)
{
int code;
struct context *context;
if((code = setup_context(op, base_awidthshow, NULL, &context)) < 0)
return code;
if((code = num_params(op - 1, 2, context->axy)) < 0)
return code;
check_type(op[-3], t_integer);
context->wschar = (char_code)op[-3].value.intval;
if((code = num_params(op - 4, 2, context->cxy)) < 0)
return code;
check_currentpoint(igs);
pop(6);
op -= 6;
context->index = i_zawidthshow0;
return comp_continue(op);
}
/*
* charpath0()
*/
int
zcharpath0(register os_ptr op)
{
int code;
struct context *context;
if((code = setup_context(op - 1, base_charpath, NULL, &context)) < 0)
return code;
check_type(*op, t_boolean);
context->charpath_flag = op->value.index;
check_currentpoint(igs);
pop(2);
op -= 2;
context->index = i_zcharpath0;
return comp_continue(op);
}
/*
* stringwidth0
*/
int
zstringwidth0(register os_ptr op)
{
int code;
struct context *context;
if((code = setup_context(op, base_stringwidth,
final_stringwidth, &context)) < 0)
return code;
context->wxy[0] = 0;
context->wxy[1] = 0;
push(1);
make_int(op - 1, 0); /* Dummy x */
make_int(op, 0); /* Dummy y */
context->index = i_zstringwidth0;
return comp_continue(op);
}
/*
* cshow
*/
int
zcshow0(register os_ptr op)
{
int code;
struct context *context;
if((code = setup_context(op, base_cshow, NULL, &context)) < 0)
return code;
check_proc(op[-1]);
context->in_cshow = 1;
context->cshow_proc = op[-1];
pop(2);
op -= 2;
context->index = i_zcshow0;
return comp_continue(op);
}
/*
* rootfont
*/
int
zrootfont(register os_ptr op)
{
push(1);
*op = istate.rootfont;
return 0;
}
/*
* findencoding
* Note: there is no encoding dictionary defined in files.
*/
int
zfindencoding(register os_ptr op)
{
return zload(op);
}
/* -------- Initialization procedure -------- */
ref name_FDepVector;
#ifdef DEBUG
ref name_FontName;
#endif
private void
zcomp_init()
{
static names_def fnd[] = {
{ "FDepVector", &name_FDepVector },
#ifdef DEBUG
{ "FontName", &name_FontName },
#endif
/* Mark the end of the initalized name list. */
names_def_end
};
init_names(fnd);
}
op_def zcomp_op_defs[] = {
{"1show0", zshow0, &i_zshow0},
{"3ashow0", zashow0, &i_zashow0},
{"4widthshow0", zwidthshow0, &i_zwidthshow0},
{"6awidthshow0", zawidthshow0, &i_zawidthshow0},
{"2charpath0", zcharpath0, &i_zcharpath0},
{"1stringwidth0", zstringwidth0, &i_zstringwidth0},
{"2cshow0", zcshow0, &i_zcshow0},
{"1rootfont", zrootfont},
{"1findencoding", zfindencoding},
op_def_end(zcomp_init)
};
/* -------- Internal procedures -------- */
private int
base_show(os_ptr op, struct context *context)
{
#ifdef DEBUG
fprintf(stderr, "base_show: %02X\n", context->code);
#endif
push(1);
make_tasv(op, t_string, a_all, 1, bytes, &context->code);
check_estack(1);
#ifdef DEBUG
fprintf(stderr, "context->index:%d\n", context->index);
#endif
push_op_estack(zshow, context->index);
return o_push_estack;
}
private int
base_ashow(os_ptr op, struct context *context)
{
push(3);
make_real(op - 2, context->axy[0]);
make_real(op - 1, context->axy[1]);
make_tasv(op, t_string, a_all, 1, bytes, &context->code);
check_estack(1);
push_op_estack(zashow, context->index);
return o_push_estack;
}
private int
base_widthshow(os_ptr op, struct context *context)
{
int wschar;
if((wschar = getwschar(context)) < 0) {
push(1);
make_tasv(op, t_string, a_all, 1, bytes, &context->code);
check_estack(1);
push_op_estack(zshow, context->index);
return o_push_estack;
}
else {
push(4);
make_real(op - 3, context->cxy[0]);
make_real(op - 2, context->cxy[1]);
make_int(op - 1, wschar);
make_tasv(op, t_string, a_all, 1, bytes, &context->code);
#ifdef DEBUG
fprintf(stderr, "wschar: %02X, code: %02X\n",
wschar, context->code);
#endif
check_estack(1);
push_op_estack(zwidthshow, context->index);
return o_push_estack;
}
}
private int
base_awidthshow(os_ptr op, struct context *context)
{
int wschar;
if((wschar = getwschar(context)) < 0) {
push(3);
make_real(op - 2, context->axy[0]);
make_real(op - 1, context->axy[1]);
make_tasv(op, t_string, a_all, 1, bytes, &context->code);
check_estack(1);
push_op_estack(zashow, context->index);
return o_push_estack;
}
else {
push(6);
make_real(op - 5, context->cxy[0]);
make_real(op - 4, context->cxy[1]);
make_int(op - 3, wschar);
make_real(op - 2, context->axy[0]);
make_real(op - 1, context->axy[1]);
make_tasv(op, t_string, a_all, 1, bytes, &context->code);
check_estack(1);
push_op_estack(zawidthshow, context->index);
return o_push_estack;
}
}
private int
base_charpath(os_ptr op, struct context *context)
{
push(2);
make_tasv(op - 1, t_string, a_all, 1, bytes, &context->code);
make_bool(op, context->charpath_flag);
check_estack(1);
push_op_estack(zcharpath, context->index);
return o_push_estack;
}
private int
base_stringwidth(os_ptr op, struct context *context)
{
int code;
float wxy[2];
if((code = num_params(op, 2, wxy)) < 0)
return code;
#ifdef DEBUG
fprintf(stderr, "wxy : %g, %g\n", wxy[0], wxy[1]);
fprintf(stderr, "context->wxy : %g, %g\n",
context->wxy[0], context->wxy[1]);
#endif
context->wxy[0] += wxy[0];
context->wxy[1] += wxy[1];
pop(1);
op --;
make_tasv(op, t_string, a_all, 1, bytes, &context->code);
check_estack(1);
push_op_estack(zstringwidth, context->index);
return o_push_estack;
}
private int
final_stringwidth(os_ptr op, struct context *context)
{
int code;
float wxy[2];
if((code = num_params(op, 2, wxy)) < 0)
return code;
context->wxy[0] += wxy[0];
context->wxy[1] += wxy[1];
#ifdef DEBUG
fprintf(stderr, "final_stringwidth: %g, %g\n",
context->wxy[0], context->wxy[1]);
#endif
make_real(op - 1, context->wxy[0]);
make_real(op, context->wxy[1]);
return 0;
}
private int
base_cshow(os_ptr op, struct context *context)
{
push(2);
make_int(op - 1, context->code);
make_tasv(op, t_string, a_all, 1, bytes, &context->code);
#ifdef DEBUG
fprintf(stderr, "base_cshow: %02X\n", context->code);
#endif
check_estack(2);
esp ++;
ref_assign(esp, &context->cshow_proc);
push_op_estack(zstringwidth, context->index);
return o_push_estack;
}
/* -------- Internal routines -------- */
#ifdef DEBUG
private int
fprints(FILE *fp, byte *str, int len)
{
int i;
for(i=0; i<len; i++)
fprintf(fp, "%02X ", str[i]);
fprintf(fp, "\n");
}
#endif
/*
* Setup the context structure
*/
private int
setup_context(os_ptr pref, int (*base_proc)(), int (*final_proc)(),
struct context **result)
{
byte *str;
int len;
struct context *context;
check_type(*pref, t_string);
str = pref->value.bytes;
len = r_size(pref);
#ifdef DEBUG
fprintf(stderr, "setup_context(): ");
fprints(stderr, str, len);
#endif
/* Allocate context structure */
context = (struct context *)
gs_malloc(1, sizeof(struct context), "comp_decode");
if(context == 0)
return e_VMerror;
/* Font stack */
context->fdepth = 0;
context->dictstack[0] = istate.font;
context->fontstack[0] = igs->font;
#ifdef DEBUG
fprintf(stderr, "fontstack[0]: %08X\n", context->fontstack[0]);
#endif
/* Mapping information */
context->font_no[0] = -1; /* specify undefined */
context->modal[0] = -1; /* specify undefined */
/* String */
context->buffer_size = len + 1;
context->buffer = (byte *)
gs_malloc(context->buffer_size, 1, "comp_decode");
if(context->buffer == 0)
return e_VMerror;
memcpy(context->buffer, str, len);
context->str = context->buffer;
context->len = len;
/* procedures */
context->base_proc = base_proc;
context->final_proc = final_proc;
/* procedure tags */
context->in_cshow = 0;
/* Push the context structure in the e-stack */
check_estack(2);
mark_estack(es_comp);
esp ++;
make_tasv(esp, t_string, 0, sizeof(struct context),
bytes, (byte *)context);
if(result != NULL)
*result = context;
return 0;
}
/*
* Free context structure
*/
private int
free_context(struct context *context)
{
gs_free((char *)context->buffer, context->buffer_size,1,"comp_decode");
gs_free((char *)context, 1, sizeof(struct context), "comp_decode");
return 0;
}
/*
* Composite String Procedure
*/
private int
comp_continue(register os_ptr op)
{
int code;
struct context *context = (struct context *)esp->value.bytes;
ref *dictstack = context->dictstack;
gs_font **fontstack = context->fontstack;
#ifdef DEBUG
fprintf(stderr, "comp_continue()\n");
fprintf(stderr, "context->str : ");
fprints(stderr, context->str, context->len);
{ gs_point pt; gs_currentpoint(igs, &pt);
fprintf(stderr, "currentpoint: %g, %g\n", pt.x, pt.y);
}
#endif
/* pop non-modal fonts */
pop_font(context);
/* restore currentfont */
if((code= gs_setfont(igs, fontstack[0])) < 0)
return code;
istate.font = dictstack[0];
if(context->len == 0) {
/* Execute Final Procedure */
if(context->final_proc != NULL &&
(code = context->final_proc(op, context)) < 0)
return code;
esp -= 2;
free_context(context);
return o_pop_estack;
}
for(;;) {
gs_font *pfont = fontstack[context->fdepth];
gs_type0_data *pdata = &pfont->data.type0_data;
#ifdef DEBUG
fprintf(stderr, "Font Mapping Loop %d\n", context->fdepth);
{
char buffer[256];
ref *pfname;
if(dict_find(&dictstack[context->fdepth],
&name_FontName, &pfname) <= 0 ||
!r_has_type(pfname, t_name))
fprintf(stderr, "Failed to get FontName\n");
else {
strncpy(buffer,
pfname->value.pname->string_bytes,
pfname->value.pname->string_size);
buffer[pfname->value.pname->string_size] = 0;
fprintf(stderr, "%s\n", buffer);
}
}
#endif
if(pfont->FontType != ft_composite)
break;
if(context->fdepth >= FontStackDepth - 1)
return e_rangecheck;
#ifdef DEBUG
fprintf(stderr, "FMapType: %d\n", pdata->FMapType);
#endif
switch(pdata->FMapType) {
case 2:
code = FMapType2(context);
break;
case 3:
code = FMapType3(context);
break;
case 4:
code = FMapType4(context);
break;
case 5:
code = FMapType5(context);
break;
case 6:
code = FMapType6(context);
break;
case 7:
code = FMapType7(context);
break;
case 8:
code = FMapType8(context);
break;
default:
return e_invalidfont;
}
if(code < 0)
return code;
}
context->code = *context->str;
context->str ++;
context->len --;
comp_setfont(context);
check_estack(1);
push_op_estack(comp_continue, context->index);
/* Execute Base Procedure */
if((code = context->base_proc(op, context)) < 0)
return code;
return o_push_estack;
}
/* -------- Font Map Decoders -------- */
/*
* 8/8 Mapping Decoder
*/
private int
FMapType2(struct context *context)
{
int code, font_no;
if(context->len < 2)
return e_rangecheck;
font_no = context->str[0];
if((code = push_font(context, font_no, 0)) < 0)
return code;
context->str ++;
context->len --;
return 0;
}
/*
* Escape Mapping Decoder
*/
private int
FMapType3(struct context *context)
{
byte esc_char;
int code, font_no;
gs_font *proot = igs->rootfont;
gs_font *pfont = context->fontstack[context->fdepth];
if(context->len <= 0)
return e_rangecheck;
/* Determine Escape Character */
if(proot->data.type0_data.FMapType == 3 ||
proot->data.type0_data.FMapType == 7)
esc_char = proot->data.type0_data.EscChar;
else
esc_char = pfont->data.type0_data.EscChar;
#ifdef DEBUG
fprintf(stderr, "EscChar: %02X\n", esc_char);
#endif
if(context->str[0] == esc_char) {
if(context->str[1] == esc_char) {
/* Upward font tree */
pop_font(context);
context->str ++;
context->len --;
return 0;
}
if(context->len < 3)
return e_rangecheck;
font_no = context->str[1];
context->str += 2;
context->len -= 2;
if((code = push_font(context, font_no, 1)) < 0)
return code;
/*
* If the pushed font (i.e. currentfont) is a base font
* and the next character is the escape character again,
* then restore the parent composite font to currentfont.
*/
if((context->fontstack[context->fdepth]->FontType !=
ft_composite) && (context->str[0] == esc_char))
pop_font(context);
}
else {
if(context->font_no[context->fdepth] < 0)
context->font_no[context->fdepth] = 0;
font_no = context->font_no[context->fdepth];
if((code = push_font(context, font_no, 1)) < 0)
return code;
}
return 0;
}
/*
* 1/7 Mapping Decoder
*/
private int
FMapType4(struct context *context)
{
int code, font_no;
if(context->len < 1)
return e_rangecheck;
font_no = (context->str[0] & 0x80 ? 1 : 0);
if((code = push_font(context, font_no, 0)) < 0)
return code;
*context->str &= 0x7f;
return 0;
}
/*
* 9/7 Mapping Decoder
*/
private int
FMapType5(struct context *context)
{
int code, font_no;
if(context->len < 2)
return e_rangecheck;
font_no = context->str[0] * 2 + (context->str[1] & 0x80 ? 1 : 0);
if((code = push_font(context, font_no, 0)) < 0)
return code;
context->str[1] &= 0x7f;
context->str ++;
context->len --;
return 0;
}
/*
* SubsVector Mapping Decoder
*/
private int
FMapType6(struct context *context)
{
ulong value, range;
int i, code, font_no, width;
gs_font *pfont = context->fontstack[context->fdepth];
gs_type0_data *pdata = &pfont->data.type0_data;
if((width = pdata->subs_width) > 4)
return e_invalidfont; /* width cannot be greater than 4 */
if(context->len < width)
return e_rangecheck;
/* Get the value from the string */
for(i=0, value=0; i<width; i++)
value = value * 256 + context->str[i];
/* Get the font number and the character code */
for(font_no=0; font_no<pdata->subs_size; font_no++) {
byte *psubs = pdata->SubsVector + font_no*width;
for(i=0, range=0; i<width; i++)
range = range * 256 + psubs[i];
if(value < range)
break;
value -= range;
}
if((code = push_font(context, font_no, 0)) < 0)
return code;
context->str += width - 1;
context->len -= width - 1;
*context->str = value;
return 0;
}
/*
* Double Escape Mapping Decoder
*/
private int
FMapType7(struct context *context)
{
byte esc_char;
int code, font_no;
gs_font *pfont = context->fontstack[context->fdepth];
if(context->len <= 0)
return e_rangecheck;
esc_char = pfont->data.type0_data.EscChar;
if(context->str[0] == esc_char) {
if(context->str[1] == esc_char) {
/* Double Escape */
if(context->len < 4)
return e_rangecheck;
font_no = context->str[2] + 256;
context->str += 3;
context->len -= 3;
}
else {
/* Single Escape */
if(context->len < 3)
return e_rangecheck;
font_no = context->str[1];
context->str += 2;
context->len -= 2;
}
if((code = push_font(context, font_no, 1)) < 0)
return code;
/*
* If the pushed font (i.e. currentfont) is a base font
* and the next character is the escape character again,
* then restore the parent composite font to currentfont.
*/
if((context->fontstack[context->fdepth]->FontType !=
ft_composite) && (context->str[0] == esc_char))
pop_font(context);
}
else {
if(context->font_no[context->fdepth] < 0)
context->font_no[context->fdepth] = 0;
font_no = context->font_no[context->fdepth];
if((code = push_font(context, font_no, 1)) < 0)
return code;
}
return 0;
}
/*
* Shift Mapping Decoder
*/
private int
FMapType8(struct context *context)
{
byte shift_in, shift_out;
int code, font_no;
gs_font *pfont = context->fontstack[context->fdepth];
if(context->len <= 0)
return e_rangecheck;
shift_in = pfont->data.type0_data.ShiftIn;
shift_out = pfont->data.type0_data.ShiftOut;
if(context->str[0] == shift_in || context->str[0] == shift_out) {
if(context->len < 2)
return e_rangecheck;
if(context->str[0] == shift_in)
font_no = 0;
else
font_no = 1;
context->str ++;
context->len --;
if((code = push_font(context, font_no, 1)) < 0)
return code;
/*
* If the pushed font (i.e. currentfont) is a base font
* and the next character is the shift character again,
* then restore the parent composite font to currentfont.
*/
if((context->fontstack[context->fdepth]->FontType !=
ft_composite) && (context->str[0] == shift_in ||
context->str[0] == shift_out))
pop_font(context);
}
else {
if(context->font_no[context->fdepth] < 0)
context->font_no[context->fdepth] = 0;
font_no = context->font_no[context->fdepth];
if((code = push_font(context, font_no, 1)) < 0)
return code;
}
return 0;
}
/*
* Push a font in the font stack
*/
private int
push_font(struct context *context, int font_no, int modal)
{
ref *parent = &context->dictstack[context->fdepth];
gs_font *pfont = context->fontstack[context->fdepth];
gs_type0_data *pdata = &pfont->data.type0_data;
int code, font_index;
ref *child, *pid, *pfdepvector;
/* pdata->FDepVector is not used because it might be out of date. */
if((code = dict_find(parent, &name_FDepVector, &pfdepvector)) < 0)
return code;
#ifdef DEBUG
fprintf(stderr, "push_font: pfdepvector->value.refs = %08X\n",
pfdepvector->value.refs);
#endif
/* Retrieve the index to a child font */
if(font_no >= pdata->encoding_size)
return e_rangecheck;
if((font_index = pdata->Encoding[font_no]) >= pdata->fdep_size)
return e_invalidfont;
/* Set mapping information */
context->font_no[context->fdepth] = font_no;
context->modal[context->fdepth] = modal;
/* Push the font in the stack */
context->fdepth ++;
child = &pfdepvector->value.refs[font_index];
context->dictstack[context->fdepth] = *child;
/* pdata->FDepVector is not used because it could be wrong. */
if((code = dict_find(child, &name_FID, &pid)) < 0)
return code;
context->fontstack[context->fdepth] = pid->value.pfont;
/* Initialize mapping information */
context->font_no[context->fdepth] = -1; /* specify undefined */
context->modal[context->fdepth] = -1; /* specify undefined */
return 0;
}
/*
* Pop fonts from the font stack until a modal font comes up
*/
private int
pop_font(struct context *context)
{
while(context->fdepth > 0) {
context->fdepth --;
if(context->modal[context->fdepth])
break;
}
return 0;
}
/*
* Retrieve the widthshow character from the context
*/
private int
getwschar(struct context *context)
{
char_code wschar = context->wschar, offset;
int fdepth = context->fdepth;
if(fdepth == 0)
return wschar;
switch(context->fontstack[fdepth - 1]->data.type0_data.FMapType) {
case 4:
case 5:
offset = context->font_no[fdepth - 1]*128;
break;
case 2:
case 3:
case 6:
case 7:
case 8:
offset = context->font_no[fdepth - 1]*256;
break;
default:
return e_invalidfont;
}
if(wschar < offset || wschar > offset + 255)
return e_rangecheck;
#ifdef DEBUG
fprintf(stderr, "font_no: %02X, wschar: %02X\n",
context->font_no[fdepth - 1], wschar);
#endif
return wschar - offset;
}
/*
* Set Basefont
*/
private int
comp_setfont(struct context *context)
{
int code;
gs_matrix mat;
gs_font *pfont, *newfont, *ffont;
ref *pdict;
/* If the font to be set is the current font, nothing be done. */
if(context->fdepth == 0)
return 0;
gs_make_identity(&mat);
if(context->fdepth != 0) {
gs_font *pfont = context->fontstack[context->fdepth - 1];
gs_matrix_multiply(&mat, &pfont->FontMatrix, &mat);
}
pdict = &context->dictstack[context->fdepth];
pfont = context->fontstack[context->fdepth];
/* Make new font */
if((code = gs_makefont(ifont_dir, pfont, &mat, &newfont, &ffont)) <0)
return code;
/* In cshow it's necessary to set the correct font dictionary in
istate.font, otherwise we need not care about FontMatrix of
the font dictionary to be set in istate.font */
if(context->in_cshow) {
ref newdict, newmat, *mbody;
if((code = dict_create(dict_maxlength(pdict), &newdict)) < 0 ||
(code = dict_copy(pdict, &newdict)) < 0)
return code;
/* Put FontMatrix into the new dictionary */
if((mbody = alloc_refs(6, "comp_setfont")) == 0)
return e_VMerror;
make_tasv_new(&newmat, t_array, a_all, 6, refs, mbody);
*(gs_matrix *)mbody = newfont->FontMatrix;
if((code = dict_put(&newdict,
&name_FontMatrix, &newmat)) < 0 ||
(code = add_FID(&newdict, newfont)) < 0)
return code;
/* Set the dictionary readonly */
r_clear_attrs(dict_access_ref(&newdict), a_write);
pdict = &newdict;
}
/* Set new font */
if((code= gs_setfont(igs, newfont)) < 0)
return code;
istate.font = *pdict;
return 0;
}