summaryrefslogtreecommitdiff
path: root/gs/psi/zchar32.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/psi/zchar32.c')
-rw-r--r--gs/psi/zchar32.c208
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)
+};