summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gsgdata.c')
-rw-r--r--base/gsgdata.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/base/gsgdata.c b/base/gsgdata.c
new file mode 100644
index 00000000..653a05a0
--- /dev/null
+++ b/base/gsgdata.c
@@ -0,0 +1,135 @@
+/* Copyright (C) 2001-2019 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 the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+
+/* Support for glyph data access */
+
+#include "memory_.h"
+#include "gx.h"
+#include "gsgdata.h"
+#include "gserrors.h"
+#include "gsmatrix.h" /* for gsfont.h */
+#include "gsstruct.h"
+#include "gxfont.h"
+
+/* GC structure descriptor */
+static ENUM_PTRS_WITH(gs_glyph_data_enum_ptrs, gs_glyph_data_t *pgd)
+ case 0: return ENUM_CONST_BYTESTRING(&pgd->bits);
+ case 1: return ENUM_OBJ(pgd->proc_data);
+ENUM_PTRS_END
+static RELOC_PTRS_WITH(gs_glyph_data_reloc_ptrs, gs_glyph_data_t *pgd)
+{
+ RELOC_CONST_BYTESTRING_VAR(pgd->bits);
+ RELOC_OBJ_VAR(pgd->proc_data);
+} RELOC_PTRS_END
+gs_public_st_composite(st_glyph_data, gs_glyph_data_t, "gs_glyph_data_t",
+ gs_glyph_data_enum_ptrs, gs_glyph_data_reloc_ptrs);
+
+/* ------ Client facilities ------ */
+
+/* Replace glyph data by a substring. */
+int
+gs_glyph_data_substring(gs_glyph_data_t *pgd, uint offset, uint size)
+{
+ if (offset > pgd->bits.size || size > pgd->bits.size - offset)
+ return_error(gs_error_rangecheck);
+ return pgd->procs->substring(pgd, offset, size);
+}
+
+/* Free the data for a glyph. */
+void
+gs_glyph_data_free(gs_glyph_data_t *pgd, client_name_t cname)
+{
+ if (pgd != 0) {
+ if (pgd->procs != 0)
+ pgd->procs->free(pgd, cname);
+ gs_glyph_data_from_null(pgd);
+ }
+}
+
+/* ------ Implementor support ------ */
+
+/* Don't manage the glyph data. */
+static void
+glyph_data_free_permanent(gs_glyph_data_t *pgd, client_name_t cname)
+{
+}
+static int
+glyph_data_substring_permanent(gs_glyph_data_t *pgd, uint offset, uint size)
+{
+ pgd->bits.data += offset;
+ pgd->bits.size = size;
+ return 0;
+}
+
+/* Manage the glyph data using the font's allocator. */
+static void
+glyph_data_free_by_font(gs_glyph_data_t *pgd, client_name_t cname)
+{
+ gs_free_const_bytestring(((gs_font *)pgd->proc_data)->memory,
+ &pgd->bits, cname);
+}
+static int
+glyph_data_substring_by_font(gs_glyph_data_t *pgd, uint offset, uint size)
+{
+ gs_font *const font = pgd->proc_data;
+ byte *data = (byte *)pgd->bits.data; /* break const */
+
+ if (pgd->bits.bytes) /* object, not string */
+ return glyph_data_substring_permanent(pgd, offset, size);
+ if (offset > 0)
+ memmove(data, data + offset, size);
+ pgd->bits.data =
+ gs_resize_string(font->memory, data, pgd->bits.size, size,
+ "glyph_data_substring"); /* shortening, can't fail */
+ pgd->bits.size = size;
+ return 0;
+}
+
+static const gs_glyph_data_procs_t no_free_procs = {
+ glyph_data_free_permanent, glyph_data_substring_permanent
+};
+static const gs_glyph_data_procs_t free_by_font_procs = {
+ glyph_data_free_by_font, glyph_data_substring_by_font
+};
+
+/*
+ * Initialize glyph data from a string or from bytes. If the font is NULL
+ * (for glyph data that is part of the font), set the glyph data freeing
+ * procedure to "do not free"; if the font is not NULL (for just-allocated
+ * glyph data), set the freeing procedure to "free using the font's
+ * allocator."
+ */
+void
+gs_glyph_data_from_string(gs_glyph_data_t *pgd, const byte *data,
+ uint size, gs_font *font)
+{
+ gs_bytestring_from_string(&pgd->bits, data, size);
+ pgd->proc_data = font;
+ pgd->procs = (font ? &free_by_font_procs : &no_free_procs);
+}
+void
+gs_glyph_data_from_bytes(gs_glyph_data_t *pgd, const byte *bytes,
+ uint offset, uint size, gs_font *font)
+{
+ gs_bytestring_from_bytes(&pgd->bits, bytes, offset, size);
+ pgd->proc_data = font;
+ pgd->procs = (font ? &free_by_font_procs : &no_free_procs);
+}
+void
+gs_glyph_data_from_null(gs_glyph_data_t *pgd)
+{
+ gs_glyph_data_from_string(pgd, NULL, 0, NULL);
+}