summaryrefslogtreecommitdiff
path: root/pxl/pxffont.c
diff options
context:
space:
mode:
Diffstat (limited to 'pxl/pxffont.c')
-rw-r--r--pxl/pxffont.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/pxl/pxffont.c b/pxl/pxffont.c
new file mode 100644
index 000000000..9ea78cfd8
--- /dev/null
+++ b/pxl/pxffont.c
@@ -0,0 +1,185 @@
+/* Portions Copyright (C) 2001 artofcode LLC.
+ Portions Copyright (C) 1996, 2001 Artifex Software Inc.
+ Portions Copyright (C) 1988, 2000 Aladdin Enterprises.
+ This software is based in part on the work of the Independent JPEG Group.
+ All Rights Reserved.
+
+ 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., 101 Lucas Valley Road #110,
+ San Rafael, CA 94903, (415)492-9861, for further information. */
+/*$Id$ */
+
+/* pxffont.c */
+/* PCL XL font-finding procedures */
+
+#include "string_.h"
+#include "gx.h"
+#include "gschar.h"
+#include "gsmatrix.h" /* for gsfont.h */
+#include "gxfont.h"
+#include "gxfont42.h"
+#include "pxoper.h"
+#include "pxstate.h"
+#include "pxfont.h"
+#include "pjtop.h"
+
+/* ---------------- Operator utilities ---------------- */
+
+#if ARCH_IS_BIG_ENDIAN
+# define pxd_native_byte_order pxd_big_endian
+#else
+# define pxd_native_byte_order 0
+#endif
+
+/* Widen and/or byte-swap a font name to Unicode if needed. */
+/* The argument is a ubyte or uint16 array; the result is a uint16 array */
+/* with the elements in native byte order. */
+/* We don't deal with mappings: we just widen 8-bit to 16-bit characters */
+/* and hope for the best.... */
+static int
+px_widen_font_name(px_value_t *pfnv, px_state_t *pxs)
+{ uint type = pfnv->type;
+
+ if ( (type & (pxd_uint16 | pxd_big_endian)) ==
+ (pxd_uint16 | pxd_native_byte_order)
+ )
+ return 0; /* already in correct format */
+ { byte *old_data = (byte *)pfnv->value.array.data; /* break const */
+ uint size = pfnv->value.array.size;
+ char16 *new_data;
+ uint i;
+
+ if ( type & pxd_on_heap )
+ old_data = (byte *)
+ (new_data =
+ (char16 *)gs_resize_object(pxs->memory, old_data,
+ size * 2, "px_widen_font_name"));
+ else
+ new_data =
+ (char16 *)gs_alloc_byte_array(pxs->memory, size, sizeof(char16),
+ "px_widen_font_name");
+ if ( new_data == 0 )
+ return_error(errorInsufficientMemory);
+ for ( i = size; i; )
+ { --i;
+ new_data[i] =
+ (type & pxd_ubyte ? old_data[i] :
+ uint16at(old_data + i * 2, type & pxd_big_endian));
+ }
+ pfnv->value.array.data = (byte *)new_data;
+ }
+ pfnv->type = (type & ~(pxd_ubyte | pxd_big_endian)) |
+ (pxd_uint16 | pxd_native_byte_order | pxd_on_heap);
+ return 0;
+}
+
+/** It seems that PXL has 10 different names for the lineprinter font
+ * one for each of the font symbol set pairs in pcl.
+ * this maps all PXL lineprinter requests to the 0N version
+ * saves ram/rom not storing 10 different versions.
+ */
+
+static int
+px_lineprinter_font_alias_name(px_value_t *pfnv, px_state_t *pxs)
+{
+ /* NB:coupling: depends on this being the first LinePrinter font in plftable.c */
+ static const unsigned short linePrinter[16] =
+ {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','0','N'};
+ unsigned short *ptr = (unsigned short *)&pfnv->value.array.data[0];
+ uint i;
+
+ if ( pfnv->value.array.size != 16 )
+ return 0;
+ for( i = 0; i < 12; i++) {
+ if ( ptr[i] != linePrinter[i] )
+ return 0; /* no match */
+ }
+ for( i = 12; i < 16; i++)
+ ptr[i] = linePrinter[i]; /* front matched now make it identical */
+ return 0;
+}
+
+/* ---------------- Operator implementations ---------------- */
+
+/* Look up a font name and return an existing font. */
+/* This procedure may widen and/or byte-swap the font name. */
+/* If this font is supposed to be built in but no .TTF file is available, */
+/* or if loading the font fails, return >= 0 and store 0 in *ppxfont. */
+int
+px_find_existing_font(px_value_t *pfnv, px_font_t **ppxfont,
+ px_state_t *pxs)
+{ int code;
+ void *pxfont;
+
+ /* Normalize the font name to Unicode. */
+ code = px_widen_font_name(pfnv, pxs);
+ if ( code < 0 )
+ return code;
+
+ /* Do pxl font aliasing */
+ code = px_lineprinter_font_alias_name(pfnv, pxs);
+ if ( code < 0 )
+ return code;
+
+ if ( px_dict_find(&pxs->font_dict, pfnv, &pxfont) ) {
+ /* Make sure this isn't a partially defined font */
+ if ( ((px_font_t *)pxfont)->pfont )
+ *ppxfont = pxfont;
+ else {
+ /* in the process of being downloaded. */
+ dprintf("font is being downloaded???\n");
+ return -1;
+ }
+ } else if ( px_dict_find(&pxs->builtin_font_dict, pfnv, &pxfont) )
+ if ( ((px_font_t *)pxfont)->pfont )
+ *ppxfont = pxfont;
+ else {
+ dprintf("corrupt pxl builtin font\n");
+ return -1;
+ }
+ else
+ return -1; /* font not found or corrupt builtin font */
+
+ return 0;
+}
+
+/* Look up a font name and return a font, possibly with substitution. */
+/* This procedure implements most of the SetFont operator. */
+/* This procedure may widen and/or byte-swap the font name. */
+int
+px_find_font(px_value_t *pfnv, uint symbol_set, px_font_t **ppxfont,
+ px_state_t *pxs)
+{
+
+ int code;
+ /* Check if we know the font already. */
+ /* Note that px_find_existing_font normalizes the font name. */
+ code = px_find_existing_font(pfnv, ppxfont, pxs);
+ /* substitute for missing builtin font */
+
+ if (code < 0) {
+ px_value_t default_font_value;
+ /* the documentation states the default font chosen here
+ is device dependent */
+ const char *default_font = "Courier ";
+ char message[px_max_error_line + 1];
+ default_font_value.type = pxd_ubyte | pxd_array;
+ default_font_value.value.array.data = default_font;
+ default_font_value.value.array.size = strlen(default_font);
+ code = px_find_existing_font(&default_font_value, ppxfont, pxs);
+ /* shouldn't fail */
+ if ( code < 0 )
+ return code;
+ message[0] = (char)NULL;
+ px_concat_font_name(message, px_max_error_line, &default_font_value);
+ strcat(message, "substituted for ");
+ px_concat_font_name(message, px_max_error_line, pfnv);
+ code = px_record_warning(message, false, pxs);
+ }
+ if ( code >= 0 )
+ return pl_load_resident_font_data_from_file(pxs->memory, *ppxfont);
+ else
+ return code;
+}