diff options
Diffstat (limited to 'gs/psi/zchar32.c')
-rw-r--r-- | gs/psi/zchar32.c | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/gs/psi/zchar32.c b/gs/psi/zchar32.c new file mode 100644 index 000000000..52c38c588 --- /dev/null +++ b/gs/psi/zchar32.c @@ -0,0 +1,208 @@ +/* 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$ */ +/* Type 32 font glyph operators */ +#include "ghost.h" +#include "oper.h" +#include "gsccode.h" /* for gxfont.h */ +#include "gsmatrix.h" +#include "gsutil.h" +#include "gxfixed.h" +#include "gxfont.h" +#include "gxfcache.h" +#include "ifont.h" +#include "igstate.h" +#include "store.h" + +/* ([wx wy llx lly urx ury] | [w0x w0y llx lly urx ury w1x w1y vx vy]) */ +/* <bitmap> <cid> <type32font> <str22> .makeglyph32 <<same with substr>> */ +static int +zmakeglyph32(i_ctx_t *i_ctx_p) +{ + os_ptr op = osp; + bool long_form; + uint msize; + double metrics[10]; + int wx, llx, lly, urx, ury; + int width, height, raster; + gs_font *pfont; + int code; + byte *str; + + check_array(op[-4]); + msize = r_size(op - 4); + switch (msize) { + case 10: + long_form = true; + break; + case 6: + long_form = false; + break; + default: + return_error(e_rangecheck); + } + code = num_params(op[-4].value.refs + msize - 1, msize, metrics); + if (code < 0) + return code; + if (~code & 0x3c) /* check llx .. ury for integers */ + return_error(e_typecheck); + check_read_type(op[-3], t_string); + llx = (int)metrics[2]; + lly = (int)metrics[3]; + urx = (int)metrics[4]; + ury = (int)metrics[5]; + width = urx - llx; + height = ury - lly; + raster = (width + 7) >> 3; + if (width < 0 || height < 0 || r_size(op - 3) != raster * height) + return_error(e_rangecheck); + check_int_leu(op[-2], 65535); + code = font_param(op - 1, &pfont); + if (code < 0) + return code; + if (pfont->FontType != ft_CID_bitmap) + return_error(e_invalidfont); + check_write_type(*op, t_string); + if (r_size(op) < 22) + return_error(e_rangecheck); + str = op->value.bytes; + if (long_form || metrics[0] != (wx = (int)metrics[0]) || + metrics[1] != 0 || height == 0 || + ((wx | width | height | (llx + 128) | (lly + 128)) & ~255) != 0 + ) { + /* Use the long form. */ + int i, n = (long_form ? 10 : 6); + + str[0] = 0; + str[1] = long_form; + for (i = 0; i < n; ++i) { + int v = (int)metrics[i]; /* no floating point widths yet */ + + str[2 + 2 * i] = (byte)(v >> 8); + str[2 + 2 * i + 1] = (byte)v; + } + r_set_size(op, 2 + n * 2); + } else { + /* Use the short form. */ + str[0] = (byte)width; + str[1] = (byte)height; + str[2] = (byte)wx; + str[3] = (byte)(llx + 128); + str[4] = (byte)(lly + 128); + r_set_size(op, 5); + } + return code; +} + +/* <cid_min> <cid_max> <type32font> .removeglyphs - */ +typedef struct { + gs_glyph cid_min, cid_max; + gs_font *font; +} font_cid_range_t; +static bool +select_cid_range(const gs_memory_t *mem, cached_char * cc, void *range_ptr) +{ + const font_cid_range_t *range = range_ptr; + + return (cc->code >= range->cid_min && + cc->code <= range->cid_max && + cc->pair->font == range->font); +} +static int +zremoveglyphs(i_ctx_t *i_ctx_p) +{ + os_ptr op = osp; + int code; + font_cid_range_t range; + + check_int_leu(op[-2], 65535); + check_int_leu(op[-1], 65535); + code = font_param(op, &range.font); + if (code < 0) + return code; + if (range.font->FontType != ft_CID_bitmap) + return_error(e_invalidfont); + range.cid_min = gs_min_cid_glyph + op[-2].value.intval; + range.cid_max = gs_min_cid_glyph + op[-1].value.intval; + gx_purge_selected_cached_chars(range.font->dir, select_cid_range, + &range); + pop(3); + return 0; +} + +/* <str5/14/22> .getmetrics32 <width> <height> <wx> ... <ury> 5/14 */ +/* <str5/14/22> .getmetrics32 <width> <height> <w0x> ... <vy> 22 */ +static int +zgetmetrics32(i_ctx_t *i_ctx_p) +{ + os_ptr op = osp; + const byte *data; + uint size; + int i, n = 6; + os_ptr wop; + + check_read_type(*op, t_string); + data = op->value.const_bytes; + size = r_size(op); + if (size < 5) + return_error(e_rangecheck); + if (data[0]) { + /* Short form. */ + int llx = (int)data[3] - 128, lly = (int)data[4] - 128; + + n = 6; + size = 5; + push(8); + make_int(op - 6, data[2]); /* wx */ + make_int(op - 5, 0); /* wy */ + make_int(op - 4, llx); + make_int(op - 3, lly); + make_int(op - 2, llx + data[0]); /* urx */ + make_int(op - 1, lly + data[1]); /* ury */ + } else { + if (data[1]) { + /* Long form, both WModes. */ + if (size < 22) + return_error(e_rangecheck); + n = 10; + size = 22; + } else { + /* Long form, WMode = 0 only. */ + if (size < 14) + return_error(e_rangecheck); + n = 6; + size = 14; + } + push(2 + n); + for (i = 0; i < n; ++i) + make_int(op - n + i, + ((int)((data[2 * i + 2] << 8) + data[2 * i + 3]) ^ 0x8000) + - 0x8000); + } + wop = op - n; + make_int(wop - 2, wop[4].value.intval - wop[2].value.intval); + make_int(wop - 1, wop[5].value.intval - wop[3].value.intval); + make_int(op, size); + return 0; +} + +/* ------ Initialization procedure ------ */ + +const op_def zchar32_op_defs[] = +{ + {"1.getmetrics32", zgetmetrics32}, + {"4.makeglyph32", zmakeglyph32}, + {"3.removeglyphs", zremoveglyphs}, + op_def_end(0) +}; |