summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'devices/vector/gdevtxtw.c')
-rw-r--r--devices/vector/gdevtxtw.c778
1 files changed, 192 insertions, 586 deletions
diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c
index d46a935e..687581d5 100644
--- a/devices/vector/gdevtxtw.c
+++ b/devices/vector/gdevtxtw.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2020 Artifex Software, Inc.
+/* Copyright (C) 2001-2021 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -36,30 +36,9 @@
#include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently First/Last Page and obejct filter */
#include "gxchar.h"
-/* #define TRACE_TXTWRITE 1 */
+#include "doc_common.h"
-extern single_glyph_list_t SingleGlyphList[];
-extern double_glyph_list_t DoubleGlyphList[];
-extern treble_glyph_list_t TrebleGlyphList[];
-extern quad_glyph_list_t QuadGlyphList[];
-/*
- * Define the structure used to return glyph width information. Note that
- * there are two different sets of width information: real-number (x,y)
- * values, which give the true advance width, and an integer value, which
- * gives an X advance width for WMode = 0 or a Y advance width for WMode = 1.
- * The return value from txt_glyph_width() indicates which of these is/are
- * valid.
- */
-typedef struct txt_glyph_width_s {
- double w;
- gs_point xy;
- gs_point v; /* glyph origin shift */
-} txt_glyph_width_t;
-typedef struct txt_glyph_widths_s {
- txt_glyph_width_t Width; /* unmodified, for Widths */
- txt_glyph_width_t real_width; /* possibly modified, for rendering */
- bool replaced_v;
-} txt_glyph_widths_t;
+/* #define TRACE_TXTWRITE 1 */
/* Structure to record the Unicode characters, the total width of the text
* recorded, and various useful attributes such as the font, size, colour
@@ -75,6 +54,8 @@ typedef struct text_list_entry_s {
gs_point FontBBox_bottomleft, FontBBox_topright;
float *Widths;
float *Advs;
+ float *GlyphWidths;
+ float *SpanDeltaX;
unsigned short *Unicode_Text;
int Unicode_Text_Size;
int render_mode;
@@ -150,15 +131,17 @@ typedef struct textw_text_enum_s {
double cdevproc_result[10];
float *Widths;
float *Advs;
+ float *GlyphWidths;
+ float *SpanDeltaX;
unsigned short *TextBuffer;
int TextBufferIndex;
text_list_entry_t *text_state;
} textw_text_enum_t;
#define private_st_textw_text_enum()\
extern_st(st_gs_text_enum);\
- gs_private_st_suffix_add0(st_textw_text_enum, textw_text_enum_t,\
+ gs_private_st_suffix_add1(st_textw_text_enum, textw_text_enum_t,\
"textw_text_enum_t", textw_text_enum_enum_ptrs, textw_text_enum_reloc_ptrs,\
- st_gs_text_enum)
+ st_gs_text_enum, pte_fallback)
private_st_textw_text_enum();
@@ -435,16 +418,30 @@ static int merge_horizontally(gx_device_txtwrite_t *tdev)
if (to->start.x - from->end.x < average_width / 2) {
/* consolidate fragments */
- unsigned short *NewText;
- float *NewWidths;
+ unsigned short *NewText = NULL;
+ float *NewWidths = NULL, *NewAdvs = NULL, *NewGlyphWidths = NULL, *NewSpanDeltaX = NULL;
NewText = (unsigned short *)gs_malloc(tdev->memory->stable_memory,
(from->Unicode_Text_Size + to->Unicode_Text_Size), sizeof(unsigned short), "txtwrite alloc working text buffer");
NewWidths = (float *)gs_malloc(tdev->memory->stable_memory,
(from->Unicode_Text_Size + to->Unicode_Text_Size), sizeof(float), "txtwrite alloc Widths array");
- if (!NewText || !NewWidths) {
+ NewAdvs = (float *)gs_malloc(tdev->memory->stable_memory,
+ (from->Unicode_Text_Size + to->Unicode_Text_Size), sizeof(float), "txtwrite alloc Advs array");
+ NewGlyphWidths = (float *)gs_malloc(tdev->memory->stable_memory,
+ (from->Unicode_Text_Size + to->Unicode_Text_Size), sizeof(float), "txtwrite alloc GlyphWidths array");
+ NewSpanDeltaX = (float *)gs_malloc(tdev->memory->stable_memory,
+ (from->Unicode_Text_Size + to->Unicode_Text_Size), sizeof(float), "txtwrite alloc SpanDeltaX array");
+ if (!NewText || !NewWidths || !NewAdvs || !NewGlyphWidths || !NewSpanDeltaX) {
if (NewText)
gs_free(tdev->memory, NewText, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+ if (NewWidths)
+ gs_free(tdev->memory, NewWidths, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+ if (NewAdvs)
+ gs_free(tdev->memory, NewAdvs, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+ if (NewGlyphWidths)
+ gs_free(tdev->memory, NewGlyphWidths, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+ if (NewSpanDeltaX)
+ gs_free(tdev->memory, NewSpanDeltaX, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
/* ran out of memory, don't consolidate */
from = from->next;
to = to->next;
@@ -459,14 +456,31 @@ static int merge_horizontally(gx_device_txtwrite_t *tdev)
memcpy(&NewText[from->Unicode_Text_Size], to->Unicode_Text, to->Unicode_Text_Size * sizeof(unsigned short));
memcpy(NewWidths, from->Widths, from->Unicode_Text_Size * sizeof(float));
memcpy(&NewWidths[from->Unicode_Text_Size], to->Widths, to->Unicode_Text_Size * sizeof(float));
+ memcpy(NewAdvs, from->Advs, from->Unicode_Text_Size * sizeof(float));
+ memcpy(&NewAdvs[from->Unicode_Text_Size], to->Advs, to->Unicode_Text_Size * sizeof(float));
+ memcpy(NewGlyphWidths, from->GlyphWidths, from->Unicode_Text_Size * sizeof(float));
+ memcpy(&NewGlyphWidths[from->Unicode_Text_Size], to->GlyphWidths, to->Unicode_Text_Size * sizeof(float));
+ memcpy(NewSpanDeltaX, from->SpanDeltaX, from->Unicode_Text_Size * sizeof(float));
+ memcpy(&NewSpanDeltaX[from->Unicode_Text_Size], to->SpanDeltaX, to->Unicode_Text_Size * sizeof(float));
+
gs_free(tdev->memory, from->Unicode_Text, from->Unicode_Text_Size, sizeof (unsigned short), "free consolidated text fragment");
gs_free(tdev->memory, to->Unicode_Text, to->Unicode_Text_Size, sizeof (unsigned short), "free consolidated text fragment");
gs_free(tdev->memory, from->Widths, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
gs_free(tdev->memory, to->Widths, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, from->Advs, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, to->Advs, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, from->GlyphWidths, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, to->GlyphWidths, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, from->SpanDeltaX, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, to->SpanDeltaX, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
gs_free(tdev->memory, to->FontName, 1, strlen(from->FontName) + 1, "free FontName");
+
from->Unicode_Text = NewText;
from->Unicode_Text_Size += to->Unicode_Text_Size;
from->Widths = NewWidths;
+ from->Advs = NewAdvs;
+ from->GlyphWidths = NewGlyphWidths;
+ from->SpanDeltaX = NewSpanDeltaX;
#ifdef TRACE_TXTWRITE
gp_fprintf(tdev->DebugFile, "After:\n\t");
gp_fwrite(from->Unicode_Text, sizeof(unsigned short), from->Unicode_Text_Size, tdev->DebugFile);
@@ -480,16 +494,30 @@ static int merge_horizontally(gx_device_txtwrite_t *tdev)
}
} else {
if (to->start.x - from->end.x < average_width *2){
- unsigned short *NewText;
- float *NewWidths;
+ unsigned short *NewText = NULL;
+ float *NewWidths = NULL, *NewAdvs = NULL, *NewGlyphWidths = NULL, *NewSpanDeltaX = NULL;
NewText = (unsigned short *)gs_malloc(tdev->memory->stable_memory,
(from->Unicode_Text_Size + to->Unicode_Text_Size + 1), sizeof(unsigned short), "txtwrite alloc text state");
NewWidths = (float *)gs_malloc(tdev->memory->stable_memory,
(from->Unicode_Text_Size + to->Unicode_Text_Size + 1), sizeof(float), "txtwrite alloc Widths array");
- if (!NewText || !NewWidths) {
+ NewAdvs = (float *)gs_malloc(tdev->memory->stable_memory,
+ (from->Unicode_Text_Size + to->Unicode_Text_Size + 1), sizeof(float), "txtwrite alloc Advs array");
+ NewGlyphWidths = (float *)gs_malloc(tdev->memory->stable_memory,
+ (from->Unicode_Text_Size + to->Unicode_Text_Size + 1), sizeof(float), "txtwrite alloc GlyphWidths array");
+ NewSpanDeltaX = (float *)gs_malloc(tdev->memory->stable_memory,
+ (from->Unicode_Text_Size + to->Unicode_Text_Size + 1), sizeof(float), "txtwrite alloc SpanDeltaX array");
+ if (!NewText || !NewWidths || !NewAdvs || !NewGlyphWidths || !NewSpanDeltaX) {
if (NewText)
gs_free(tdev->memory, NewText, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+ if (NewWidths)
+ gs_free(tdev->memory, NewWidths, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+ if (NewAdvs)
+ gs_free(tdev->memory, NewAdvs, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+ if (NewGlyphWidths)
+ gs_free(tdev->memory, NewGlyphWidths, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
+ if (NewSpanDeltaX)
+ gs_free(tdev->memory, NewSpanDeltaX, from->Unicode_Text_Size + to->Unicode_Text_Size, sizeof (unsigned short), "free working text fragment");
/* ran out of memory, don't consolidate */
from = from->next;
to = to->next;
@@ -500,14 +528,34 @@ static int merge_horizontally(gx_device_txtwrite_t *tdev)
memcpy(NewWidths, from->Widths, from->Unicode_Text_Size * sizeof(float));
NewWidths[from->Unicode_Text_Size] = to->start.x - from->end.x;
memcpy(&NewWidths[from->Unicode_Text_Size + 1], to->Widths, to->Unicode_Text_Size * sizeof(float));
+ memcpy(NewAdvs, from->Advs, from->Unicode_Text_Size * sizeof(float));
+ NewAdvs[from->Unicode_Text_Size] = to->start.x - from->end.x;
+ memcpy(&NewAdvs[from->Unicode_Text_Size + 1], to->Advs, to->Unicode_Text_Size * sizeof(float));
+ memcpy(NewGlyphWidths, from->GlyphWidths, from->Unicode_Text_Size * sizeof(float));
+ NewGlyphWidths[from->Unicode_Text_Size] = 0.0;
+ memcpy(&NewGlyphWidths[from->Unicode_Text_Size + 1], to->GlyphWidths, to->Unicode_Text_Size * sizeof(float));
+ memcpy(NewSpanDeltaX, from->SpanDeltaX, from->Unicode_Text_Size * sizeof(float));
+ NewSpanDeltaX[from->Unicode_Text_Size] = 0;
+ memcpy(&NewSpanDeltaX[from->Unicode_Text_Size + 1], to->SpanDeltaX, to->Unicode_Text_Size * sizeof(float));
+
gs_free(tdev->memory, from->Unicode_Text, from->Unicode_Text_Size, sizeof (unsigned short), "free consolidated text fragment");
gs_free(tdev->memory, to->Unicode_Text, to->Unicode_Text_Size, sizeof (unsigned short), "free consolidated text fragment");
gs_free(tdev->memory, from->Widths, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
gs_free(tdev->memory, to->Widths, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, from->Advs, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, to->Advs, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, from->GlyphWidths, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, to->GlyphWidths, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, from->SpanDeltaX, from->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
+ gs_free(tdev->memory, to->SpanDeltaX, to->Unicode_Text_Size, sizeof (float), "free consolidated Widths array");
gs_free(tdev->memory, to->FontName, 1, strlen(from->FontName) + 1, "free FontName");
+
from->Unicode_Text = NewText;
from->Unicode_Text_Size += to->Unicode_Text_Size + 1;
from->Widths = NewWidths;
+ from->Advs = NewAdvs;
+ from->GlyphWidths = NewGlyphWidths;
+ from->SpanDeltaX = NewSpanDeltaX;
from->end = to->end;
from->next = to->next;
if (from->next)
@@ -839,34 +887,54 @@ static int decorated_text_output(gx_device_txtwrite_t *tdev)
static int extract_text_output(gx_device_txtwrite_t *tdev)
{
text_list_entry_t* entry;
+ gp_fprintf(tdev->file, "<?xml version=\"1.0\"?>\n");
gp_fprintf(tdev->file, "<page>\n");
for (entry = tdev->PageData.unsorted_text_list;
entry;
entry = entry->next
) {
- float x = entry->start.x;
+
int i;
- gp_fprintf(tdev->file,
- "<span bbox=\"%0.4f %0.4f %0.4f %0.4f\" font=\"%s\" size=\"%0.4f\">\n",
- entry->start.x,
- entry->start.y,
- entry->end.x,
- entry->end.y,
- entry->FontName,
- entry->size
+ float x = entry->start.x - entry->matrix.tx;
+ gp_fprintf(tdev->file, "<span");
+ gp_fprintf(tdev->file, " ctm=\"%f %f %f %f %f %f\"",
+ entry->matrix.xx,
+ entry->matrix.xy,
+ entry->matrix.yx,
+ entry->matrix.yy,
+ entry->matrix.tx,
+ entry->matrix.ty
+ );
+ gp_fprintf(tdev->file, " ctm_orig=\"%f %f %f %f %f %f\"",
+ entry->matrix.xx,
+ entry->matrix.xy,
+ entry->matrix.yx,
+ entry->matrix.yy,
+ entry->matrix.tx,
+ entry->matrix.ty
+ );
+ gp_fprintf(tdev->file, " trm=\"%lf %f %f %lf %f %f\"",
+ entry->size,
+ 0.0f,
+ 0.0f,
+ entry->size,
+ 0.0f,
+ 0.0f
);
+ gp_fprintf(tdev->file, " len=\"%i\"", entry->Unicode_Text_Size);
+ gp_fprintf(tdev->file, " wmode=\"%i\"", entry->wmode);
+ gp_fprintf(tdev->file, " font_name=\"%s\"", entry->FontName);
+ gp_fprintf(tdev->file, ">\n");
for (i=0; i<entry->Unicode_Text_Size; i++) {
- float x_next = x + entry->Widths[i];
- char escaped[32];
- escaped_Unicode(entry->Unicode_Text[i], escaped);
+ float x_next = x + entry->SpanDeltaX[i];
+ int c = entry->Unicode_Text[i];
gp_fprintf(tdev->file,
- "<char bbox=\"%0.4f %0.4f %0.4f %0.4f\" c=\"%s\" adv=\"%0.4f\"/>\n",
+ "<char x=\"%f\" y=\"%f\" c=\"%c\" ucs=\"%u\" adv=\"%f\"/>\n",
x,
- entry->start.y,
- x_next,
- entry->end.y,
- escaped,
- entry->Advs[i]
+ entry->start.y - entry->matrix.ty,
+ (c >= 32 && c < 127 && c != '"') ? c : '.',
+ c,
+ entry->GlyphWidths[i] / entry->size
);
x = x_next;
}
@@ -935,6 +1003,8 @@ txtwrite_output_page(gx_device * dev, int num_copies, int flush)
gs_free(tdev->memory, x_entry->Unicode_Text, x_entry->Unicode_Text_Size, sizeof (usnigned short), "txtwrite free text fragment text buffer");
gs_free(tdev->memory, x_entry->Widths, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free widths array");
gs_free(tdev->memory, x_entry->Advs, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free advs array");
+ gs_free(tdev->memory, x_entry->GlyphWidths, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free widths array");
+ gs_free(tdev->memory, x_entry->SpanDeltaX, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free advs array");
gs_free(tdev->memory, x_entry->FontName, 1, strlen(x_entry->FontName) + 1, "txtwrite free Font Name");
if (x_entry->next) {
x_entry = x_entry->next;
@@ -961,6 +1031,8 @@ txtwrite_output_page(gx_device * dev, int num_copies, int flush)
gs_free(tdev->memory, x_entry->Unicode_Text, x_entry->Unicode_Text_Size, sizeof (usnigned short), "txtwrite free unsorted text fragment text buffer");
gs_free(tdev->memory, x_entry->Widths, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free widths array");
gs_free(tdev->memory, x_entry->Advs, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free advs array");
+ gs_free(tdev->memory, x_entry->GlyphWidths, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free widths array");
+ gs_free(tdev->memory, x_entry->SpanDeltaX, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free advs array");
gs_free(tdev->memory, x_entry->FontName, 1, strlen(x_entry->FontName) + 1, "txtwrite free Font Name");
gs_free(tdev->memory, x_entry, 1, sizeof(text_list_entry_t), "txtwrite free unsorted text fragment");
x_entry = next_x;
@@ -1231,134 +1303,6 @@ txtwrite_stroke_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
/* ------ Text imaging ------ */
-static int
-txtwrite_font_orig_matrix(const gs_font *font, gs_glyph cid, gs_matrix *pmat)
-{
- int code;
-
- switch (font->FontType) {
- case ft_composite: /* subfonts have their own FontMatrix */
- case ft_TrueType:
- case ft_CID_TrueType:
- /* The TrueType FontMatrix is 1 unit per em, which is what we want. */
- gs_make_identity(pmat);
- return 0;
- case ft_encrypted:
- case ft_encrypted2:
- case ft_CID_encrypted:
- case ft_user_defined:
- case ft_PCL_user_defined:
- case ft_GL2_stick_user_defined:
- case ft_GL2_531:
- /*
- * Type 1 fonts are supposed to use a standard FontMatrix of
- * [0.001 0 0 0.001 0 0], with a 1000-unit cell. However,
- * Windows NT 4.0 creates Type 1 fonts, apparently derived from
- * TrueType fonts, that use a 2048-unit cell and corresponding
- * FontMatrix. Also, some PS programs perform font scaling by
- * replacing FontMatrix like this :
- *
- * /f12 /Times-Roman findfont
- * copyfont % (remove FID)
- * dup /FontMatrix [0.012 0 0 0.012 0 0] put
- * definefont
- * /f12 1 selectfont
- *
- * Such fonts are their own "base font", but the orig_matrix
- * must still be set to 0.001, not 0.012 .
- *
- * The old code used a heuristic to detect and correct for this here.
- * Unfortunately it doesn't work properly when it meets a font
- * with FontMatrix like this :
- *
- * /FontMatrix [1 2288 div 0 0 1 2288 div 0 0 ] def
- *
- * (the bug 686970). Also comparefiles\455690.pdf appears to
- * have similar problem. Therefore we added a support to lib/gs_fonts.ps,
- * src/zbfont.c, src/gsfont.c that provides an acces to the original
- * font via a special key OrigFont added to the font dictionary while definefont.
- * Now we work through this access with PS interpreter,
- * but keep the old heuristic for other clients.
- */
- {
- const gs_font *base_font = font;
-
- while (base_font->base != base_font)
- base_font = base_font->base;
- if (font->FontType == ft_user_defined ||
- font->FontType == ft_PCL_user_defined ||
- font->FontType == ft_GL2_stick_user_defined ||
- font->FontType == ft_GL2_531)
- *pmat = base_font->FontMatrix;
- else if (base_font->orig_FontMatrix.xx != 0 || base_font->orig_FontMatrix.xy != 0 ||
- base_font->orig_FontMatrix.yx != 0 || base_font->orig_FontMatrix.yy != 0)
- *pmat = base_font->orig_FontMatrix;
- else {
- /* Must not happen with PS interpreter.
- Provide a hewuristic for other clients.
- */
- if (base_font->FontMatrix.xx == 1.0/2048 &&
- base_font->FontMatrix.xy == 0 &&
- base_font->FontMatrix.yx == 0 &&
- any_abs(base_font->FontMatrix.yy) == 1.0/2048
- )
- *pmat = base_font->FontMatrix;
- else
- gs_make_scaling(0.001, 0.001, pmat);
- }
- }
- if (font->FontType == ft_CID_encrypted && cid != -1) {
- int fidx;
-
- if (cid < GS_MIN_CID_GLYPH)
- cid = GS_MIN_CID_GLYPH;
- code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
- cid, NULL, &fidx);
- if (code < 0) {
- code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
- (gs_glyph)GS_MIN_CID_GLYPH, NULL, &fidx);
- }
- if (code >= 0) {
- gs_matrix_multiply(&(gs_cid0_indexed_font(font, fidx)->FontMatrix),
- pmat, pmat);
- }
- }
- return 0;
- default:
- return_error(gs_error_rangecheck);
- }
-}
-
-/*
- * Special version of txtwrite_font_orig_matrix(), that considers FDArray font's FontMatrix too.
- * Called only by txt_glyph_width().
- * 'cid' is only consulted if 'font' is a CIDFontType 0 CID font.
- */
-static int
-glyph_orig_matrix(const gs_font *font, gs_glyph cid, gs_matrix *pmat)
-{
- int code = txtwrite_font_orig_matrix(font, cid, pmat);
- if (code >= 0) {
- if (font->FontType == ft_CID_encrypted) {
- int fidx;
-
- if (cid < GS_MIN_CID_GLYPH)
- cid = GS_MIN_CID_GLYPH;
- code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
- cid, NULL, &fidx);
- if (code < 0) {
- code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
- (gs_glyph)GS_MIN_CID_GLYPH, NULL, &fidx);
- }
- if (code >= 0) {
- gs_matrix_multiply(&(gs_cid0_indexed_font(font, fidx)->FontMatrix),
- pmat, pmat);
- }
- }
- }
- return code;
-}
-
/*
* Compute the cached values in the text processing state from the text
* parameters, current_font, and pgs->ctm. Return either an error code (<
@@ -1389,42 +1333,6 @@ transform_delta_inverse(const gs_point *pdelta, const gs_matrix *pmat,
return 0;
}
-static
-float txt_calculate_text_size(gs_gstate *pgs, gs_font *ofont,
- const gs_matrix *pfmat, gs_matrix *smat, gs_matrix *tmat,
- gs_font *font, gx_device *pdev)
-{
- gs_matrix orig_matrix;
- double
- sx = pdev->HWResolution[0] / 72.0,
- sy = pdev->HWResolution[1] / 72.0;
- float size;
-
- /* Get the original matrix of the base font. */
-
- txtwrite_font_orig_matrix(ofont, -1, &orig_matrix);
- /* Compute the scaling matrix and combined matrix. */
-
- if (gs_matrix_invert(&orig_matrix, smat) < 0) {
- gs_make_identity(smat);
- return 1; /* Arbitrary */
- }
- gs_matrix_multiply(smat, pfmat, smat);
- *tmat = ctm_only(pgs);
- tmat->tx = tmat->ty = 0;
- gs_matrix_multiply(smat, tmat, tmat);
-
- /* Try to find a reasonable size value. */
-
- size = hypot(tmat->yx, tmat->yy) / sy;
- if (size < 0.01)
- size = hypot(tmat->xx, tmat->xy) / sx;
- if (size < 0.01)
- size = 1;
-
- return(size);
-}
-
static int
txt_update_text_state(text_list_entry_t *ppts,
const textw_text_enum_t *penum,
@@ -1474,13 +1382,6 @@ txt_update_text_state(text_list_entry_t *ppts,
ppts->size = size;
ppts->matrix = tmat;
- ppts->render_mode = penum->pgs->text_rendering_mode;
- ppts->FontName = (char *)gs_malloc(pdev->memory->stable_memory, 1,
- font->font_name.size + 1, "txtwrite alloc font name");
- if (!ppts->FontName)
- return gs_note_error(gs_error_VMerror);
- memcpy(ppts->FontName, font->font_name.chars, font->font_name.size);
- ppts->FontName[font->font_name.size] = 0x00;
ppts->render_mode = font->WMode;
if (font->PaintType == 2 && penum->pgs->text_rendering_mode == 0)
@@ -1512,227 +1413,6 @@ txt_update_text_state(text_list_entry_t *ppts,
return (code < 0 ? code : mask);
}
-static int
-store_glyph_width(txt_glyph_width_t *pwidth, int wmode, const gs_matrix *scale,
- const gs_glyph_info_t *pinfo)
-{
- double w, v;
-
- gs_distance_transform(pinfo->width[wmode].x, pinfo->width[wmode].y, scale, &pwidth->xy);
- if (wmode)
- w = pwidth->xy.y, v = pwidth->xy.x;
- else
- w = pwidth->xy.x, v = pwidth->xy.y;
- if (v != 0)
- return 1;
- pwidth->w = w;
- gs_distance_transform(pinfo->v.x, pinfo->v.y, scale, &pwidth->v);
- return 0;
-}
-
-static int
-get_missing_width(gs_font *font, int wmode, const gs_matrix *scale_c,
- txt_glyph_widths_t *pwidths)
-{
- gs_font_info_t finfo;
- int code;
-
- code = font->procs.font_info((gs_font *)font, NULL,
- FONT_INFO_MISSING_WIDTH, &finfo);
- if (code < 0)
- return code;
- if (!(finfo.members & FONT_INFO_MISSING_WIDTH))
- return_error(gs_error_undefined);
-
- if (wmode) {
- gs_distance_transform(0.0, -finfo.MissingWidth, scale_c, &pwidths->real_width.xy);
- pwidths->Width.xy.x = 0;
- pwidths->Width.xy.y = pwidths->real_width.xy.y;
- pwidths->Width.w = pwidths->real_width.w =
- pwidths->Width.xy.y;
- pwidths->Width.v.x = - pwidths->Width.xy.y / 2;
- pwidths->Width.v.y = - pwidths->Width.xy.y;
- } else {
- gs_distance_transform(finfo.MissingWidth, 0.0, scale_c, &pwidths->real_width.xy);
- pwidths->Width.xy.x = pwidths->real_width.xy.x;
- pwidths->Width.xy.y = 0;
- pwidths->Width.w = pwidths->real_width.w =
- pwidths->Width.xy.x;
- pwidths->Width.v.x = pwidths->Width.v.y = 0;
- }
- /*
- * Don't mark the width as known, just in case this is an
- * incrementally defined font.
- */
- return 1;
-}
-
-/*
- * Get the widths (unmodified from the copied font,
- * and possibly modified from the original font) of a given glyph.
- * Return 1 if the width was defaulted to MissingWidth.
- * Return TEXT_PROCESS_CDEVPROC if a CDevProc callout is needed.
- * cdevproc_result != NULL if we restart after a CDevProc callout.
- */
-static int
-txt_glyph_widths(gs_font *font, int wmode, gs_glyph glyph,
- gs_font *orig_font, txt_glyph_widths_t *pwidths,
- const double cdevproc_result[10])
-{
- gs_font *ofont = orig_font;
- gs_glyph_info_t info;
- gs_matrix scale_c, scale_o;
- int code, rcode = 0;
- gs_point v;
- int allow_cdevproc_callout = (orig_font->FontType == ft_CID_TrueType
- || orig_font->FontType == ft_CID_encrypted
- ? GLYPH_INFO_CDEVPROC : 0); /* fixme : allow more font types. */
-
- if (ofont->FontType == ft_composite)
- return_error(gs_error_unregistered); /* Must not happen. */
- code = glyph_orig_matrix((const gs_font *)font, glyph, &scale_c);
- if (code < 0)
- return code;
- code = glyph_orig_matrix(ofont, glyph, &scale_o);
- if (code < 0)
- return code;
- gs_matrix_scale(&scale_c, 1000.0, 1000.0, &scale_c);
- gs_matrix_scale(&scale_o, 1000.0, 1000.0, &scale_o);
- pwidths->Width.v.x = pwidths->Width.v.y = 0;
- pwidths->real_width.v.x = pwidths->real_width.v.y = 0;
- pwidths->replaced_v = false;
- if (glyph == GS_NO_GLYPH)
- return get_missing_width(font, wmode, &scale_c, pwidths);
- code = font->procs.glyph_info((gs_font *)font, glyph, NULL,
- GLYPH_INFO_WIDTH0 |
- (GLYPH_INFO_WIDTH0 << wmode) |
- GLYPH_INFO_OUTLINE_WIDTHS |
- (GLYPH_INFO_VVECTOR0 << wmode),
- &info);
- /* For CID fonts the PDF spec requires the x-component of v-vector
- to be equal to half glyph width, and AR5 takes it from W, DW.
- So make a compatibe data here.
- */
- if (font->FontType != ft_PCL_user_defined && font->FontType != ft_GL2_stick_user_defined &&
- font->FontType != ft_GL2_531
- && (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))) {
- code = get_missing_width(font, wmode, &scale_c, pwidths);
- if (code < 0)
- return code;
- else
- v.y = pwidths->Width.v.y;
- if (wmode && (ofont->FontType == ft_CID_encrypted ||
- ofont->FontType == ft_CID_TrueType)) {
- txt_glyph_widths_t widths1;
-
- if (get_missing_width(font, 0, &scale_c, &widths1) < 0)
- v.x = 0;
- else
- v.x = widths1.Width.w / 2;
- } else
- v.x = pwidths->Width.v.x;
- } else if (code < 0)
- return code;
- else {
- code = store_glyph_width(&pwidths->Width, wmode, &scale_c, &info);
- if (code < 0)
- return code;
- rcode |= code;
- if (info.members & (GLYPH_INFO_VVECTOR0 << wmode))
- gs_distance_transform(info.v.x, info.v.y, &scale_c, &v);
- else
- v.x = v.y = 0;
- if (wmode && (ofont->FontType == ft_CID_encrypted ||
- ofont->FontType == ft_CID_TrueType)) {
- if (info.members & (GLYPH_INFO_WIDTH0 << wmode)) {
- gs_point xy;
-
- gs_distance_transform(info.width[0].x, info.width[0].y, &scale_c, &xy);
- v.x = xy.x / 2;
- } else {
- txt_glyph_widths_t widths1;
-
- if (get_missing_width(font, 0, &scale_c, &widths1) < 0)
- v.x = 0;
- else
- v.x = widths1.Width.w / 2;
- }
- }
- }
- pwidths->Width.v = v;
- /* Skip only if not paralel to the axis. */
- if (code > 0 && ofont->FontType != ft_CID_encrypted &&
- ofont->FontType != ft_CID_TrueType)
- pwidths->Width.xy.x = pwidths->Width.xy.y = pwidths->Width.w = 0;
- if (cdevproc_result == NULL) {
- info.members = 0;
- code = ofont->procs.glyph_info(ofont, glyph, NULL,
- (GLYPH_INFO_WIDTH0 << wmode) |
- (GLYPH_INFO_VVECTOR0 << wmode) |
- allow_cdevproc_callout,
- &info);
- /* fixme : Move this call before cfont->procs.glyph_info. */
- if (info.members & GLYPH_INFO_CDEVPROC) {
- if (allow_cdevproc_callout)
- return TEXT_PROCESS_CDEVPROC;
- else
- return_error(gs_error_rangecheck);
- }
- } else {
- info.width[0].x = cdevproc_result[0];
- info.width[0].y = cdevproc_result[1];
- info.width[1].x = cdevproc_result[6];
- info.width[1].y = cdevproc_result[7];
- info.v.x = (wmode ? cdevproc_result[8] : 0);
- info.v.y = (wmode ? cdevproc_result[9] : 0);
- info.members = (GLYPH_INFO_WIDTH0 << wmode) |
- (wmode ? GLYPH_INFO_VVECTOR1 : 0);
- code = 0;
- }
- if (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))
- pwidths->real_width = pwidths->Width;
- else if (code < 0)
- return code;
- else {
- if ((info.members & (GLYPH_INFO_VVECTOR0 | GLYPH_INFO_VVECTOR1)) != 0)
- pwidths->replaced_v = true;
- else
- info.v.x = info.v.y = 0;
- code = store_glyph_width(&pwidths->real_width, wmode, &scale_o, &info);
- if (code < 0)
- return code;
- rcode |= code;
- gs_distance_transform(info.v.x, info.v.y, &scale_o, &pwidths->real_width.v);
- }
- return rcode;
-}
-
-static void
-txt_char_widths_to_uts(gs_font *font /* may be NULL for non-Type3 */,
- txt_glyph_widths_t *pwidths)
-{
- if (font && (font->FontType == ft_user_defined ||
- font->FontType == ft_PCL_user_defined ||
- font->FontType == ft_GL2_stick_user_defined ||
- font->FontType == ft_GL2_531)) {
- gs_matrix *pmat = &font->orig_FontMatrix;
-
- pwidths->Width.xy.x *= pmat->xx; /* formula simplified based on wy in glyph space == 0 */
- pwidths->Width.xy.y = 0.0; /* WMode == 0 for PDF Type 3 fonts */
- gs_distance_transform(pwidths->real_width.xy.x, pwidths->real_width.xy.y, pmat, &pwidths->real_width.xy);
- } else {
- /*
- * For other font types:
- * - PDF design->text space is a simple scaling by 0.001.
- * - The Width.xy.x/y that should be zeroed-out per 5.3.3 "Text Space Details" is already 0.
- */
- pwidths->Width.xy.x /= 1000.0;
- pwidths->Width.xy.y /= 1000.0;
- pwidths->real_width.xy.x /= 1000.0;
- pwidths->real_width.xy.y /= 1000.0;
- }
-}
-
/* Simple routine to update the current point by the accumulated width of the
* text.
*/
@@ -1744,142 +1424,6 @@ txt_shift_text_currentpoint(textw_text_enum_t *penum, gs_point *wpt)
fixed2float(penum->origin.y) + wpt->y);
}
-/* Try to convert glyph names/character codes to Unicode. We first try to see
- * if we have any Unicode information either from a ToUnicode CMap or GlyphNames2Unicode
- * table. If that fails we look at the glyph name to see if it starts 'uni'
- * in which case we assume the remainder of the name is the Unicode value. If
- * its not a glyph of that form then we search a bunch of tables whcih map standard
- * glyph names to Unicode code points. If that fails we finally just return the character code.
- */
-static int get_unicode(textw_text_enum_t *penum, gs_font *font, gs_glyph glyph, gs_char ch, unsigned short *Buffer)
-{
- int code;
- gs_const_string gnstr;
- unsigned short fallback = ch;
- ushort *unicode = NULL;
- int length;
-
- length = font->procs.decode_glyph((gs_font *)font, glyph, ch, NULL, 0);
- if (length == 0) {
- if (glyph != GS_NO_GLYPH) {
- code = font->procs.glyph_name(font, glyph, &gnstr);
- if (code >= 0 && gnstr.size == 7) {
- if (!memcmp(gnstr.data, "uni", 3)) {
- static const char *hexdigits = "0123456789ABCDEF";
- char *d0 = strchr(hexdigits, gnstr.data[3]);
- char *d1 = strchr(hexdigits, gnstr.data[4]);
- char *d2 = strchr(hexdigits, gnstr.data[5]);
- char *d3 = strchr(hexdigits, gnstr.data[6]);
-
- if (d0 != NULL && d1 != NULL && d2 != NULL && d3 != NULL) {
- *Buffer++ = ((d0 - hexdigits) << 12) + ((d1 - hexdigits) << 8) + ((d2 - hexdigits) << 4) + (d3 - hexdigits);
- return 1;
- }
- }
- }
- if (length == 0) {
- single_glyph_list_t *sentry = SingleGlyphList;
- double_glyph_list_t *dentry = DoubleGlyphList;
- treble_glyph_list_t *tentry = TrebleGlyphList;
- quad_glyph_list_t *qentry = QuadGlyphList;
-
- /* Search glyph to single Unicode value table */
- while (sentry->Glyph != 0) {
- if (sentry->Glyph[0] < gnstr.data[0]) {
- sentry++;
- continue;
- }
- if (sentry->Glyph[0] > gnstr.data[0]){
- break;
- }
- if (strlen(sentry->Glyph) == gnstr.size) {
- if(memcmp(gnstr.data, sentry->Glyph, gnstr.size) == 0) {
- *Buffer = sentry->Unicode;
- return 1;
- }
- }
- sentry++;
- }
-
- /* Search glyph to double Unicode value table */
- while (dentry->Glyph != 0) {
- if (dentry->Glyph[0] < gnstr.data[0]) {
- dentry++;
- continue;
- }
- if (dentry->Glyph[0] > gnstr.data[0]){
- break;
- }
- if (strlen(dentry->Glyph) == gnstr.size) {
- if(memcmp(gnstr.data, dentry->Glyph, gnstr.size) == 0) {
- memcpy(Buffer, dentry->Unicode, 2);
- return 2;
- }
- }
- dentry++;
- }
-
- /* Search glyph to triple Unicode value table */
- while (tentry->Glyph != 0) {
- if (tentry->Glyph[0] < gnstr.data[0]) {
- tentry++;
- continue;
- }
- if (tentry->Glyph[0] > gnstr.data[0]){
- break;
- }
- if (strlen(tentry->Glyph) == gnstr.size) {
- if(memcmp(gnstr.data, tentry->Glyph, gnstr.size) == 0) {
- memcpy(Buffer, tentry->Unicode, 3);
- return 3;
- }
- }
- tentry++;
- }
-
- /* Search glyph to quadruple Unicode value table */
- while (qentry->Glyph != 0) {
- if (qentry->Glyph[0] < gnstr.data[0]) {
- qentry++;
- continue;
- }
- if (qentry->Glyph[0] > gnstr.data[0]){
- break;
- }
- if (strlen(qentry->Glyph) == gnstr.size) {
- if(memcmp(gnstr.data, qentry->Glyph, gnstr.size) == 0) {
- memcpy(Buffer, qentry->Unicode, 4);
- return 4;
- }
- }
- qentry++;
- }
- }
- }
- *Buffer = fallback;
- return 1;
- } else {
- char *b, *u;
- int l = length - 1;
-
- unicode = (ushort *)gs_alloc_bytes(penum->dev->memory, length, "temporary Unicode array");
- length = font->procs.decode_glyph((gs_font *)font, glyph, ch, unicode, length);
-#if ARCH_IS_BIG_ENDIAN
- memcpy(Buffer, unicode, length);
-#else
- b = (char *)Buffer;
- u = (char *)unicode;
-
- for (l=0;l<length;l+=2, u+=2){
- *b++ = *(u+1);
- *b++ = *u;
- }
-#endif
- gs_free_object(penum->dev->memory, unicode, "free temporary unicode buffer");
- return length / sizeof(short);
- }
-}
-
/* Routines to enumerate each glyph/character code in turn, find its width
* so that we can update the current point and find the end of the text, convert
* to Unicode if at all possible, and store some state such as the font, colour
@@ -1930,7 +1474,7 @@ txtwrite_process_cmap_text(gs_text_enum_t *pte)
code = gs_matrix_multiply(&subfont->FontMatrix, &pte->orig_font->FontMatrix, &m3);
if (code < 0)
return code;
- code = txt_update_text_state(penum->text_state, (textw_text_enum_t *)pte, pte->orig_font, &m3);
+ code = txt_update_text_state(penum->text_state, (textw_text_enum_t *)pte, subfont, &m3);
if (code < 0)
return code;
txt_char_widths_to_uts(pte->orig_font, &widths); /* convert design->text space */
@@ -1940,6 +1484,8 @@ txtwrite_process_cmap_text(gs_text_enum_t *pte)
pte->returned.total_width.x += wanted.x;
pte->returned.total_width.y += wanted.y;
penum->Widths[penum->TextBufferIndex] = wanted.x;
+ penum->GlyphWidths[penum->TextBufferIndex] = widths.real_width.xy.x * penum->text_state->size;
+ penum->SpanDeltaX[penum->TextBufferIndex] = widths.real_width.xy.x * penum->text_state->size;
if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
gs_point tpt;
@@ -1961,7 +1507,8 @@ txtwrite_process_cmap_text(gs_text_enum_t *pte)
pte->returned.total_width.y += dpt.y;
penum->Widths[penum->TextBufferIndex] += dpt.x;
- penum->TextBufferIndex += get_unicode(penum, (gs_font *)pte->orig_font, glyph, chr, &penum->TextBuffer[penum->TextBufferIndex]);
+ penum->GlyphWidths[penum->TextBufferIndex] += dpt.x;
+ penum->TextBufferIndex += txt_get_unicode(penum->dev, (gs_font *)pte->orig_font, glyph, chr, &penum->TextBuffer[penum->TextBufferIndex]);
break;
case 2: /* end of string */
return 0;
@@ -2028,6 +1575,8 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
pte->returned.total_width.y += wanted.y;
penum->Widths[penum->TextBufferIndex] = wanted.x;
penum->Advs[penum->TextBufferIndex] = wanted.x;
+ penum->GlyphWidths[penum->TextBufferIndex] = widths.real_width.xy.x * penum->text_state->size;
+ penum->SpanDeltaX[penum->TextBufferIndex] = widths.real_width.xy.x * penum->text_state->size;
if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
gs_point tpt;
@@ -2049,13 +1598,16 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
pte->returned.total_width.y += dpt.y;
penum->Widths[penum->TextBufferIndex] += dpt.x;
- code = get_unicode(penum, (gs_font *)pte->orig_font, glyph, ch, &penum->TextBuffer[penum->TextBufferIndex]);
+ penum->SpanDeltaX[penum->TextBufferIndex] += dpt.x;
+ code = txt_get_unicode(penum->dev, (gs_font *)pte->orig_font, glyph, ch, &penum->TextBuffer[penum->TextBufferIndex]);
/* If a single text code returned multiple Unicode values, then we need to set the
* 'extra' code points' widths to 0.
*/
if (code > 1) {
memset(&penum->Widths[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
memset(&penum->Advs[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
+ memset(&penum->GlyphWidths[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
+ memset(&penum->SpanDeltaX[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
}
penum->TextBufferIndex += code;
/* gs_moveto_aux(penum->pgs, gx_current_path(penum->pgs),
@@ -2169,6 +1721,7 @@ txt_add_sorted_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
static int
txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
{
+ gs_font *font = penum->current_font;
text_list_entry_t *unsorted_entry, *t;
#ifdef TRACE_TXTWRITE
@@ -2216,10 +1769,28 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
if (!penum->text_state->Advs)
return gs_note_error(gs_error_VMerror);
+ penum->text_state->GlyphWidths = (float *)gs_malloc(tdev->memory->stable_memory,
+ penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
+ if (!penum->text_state->GlyphWidths)
+ return gs_note_error(gs_error_VMerror);
+ penum->text_state->SpanDeltaX = (float *)gs_malloc(tdev->memory->stable_memory,
+ penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
+ if (!penum->text_state->SpanDeltaX)
+ return gs_note_error(gs_error_VMerror);
memset(penum->text_state->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
memcpy(penum->text_state->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
memset(penum->text_state->Advs, 0x00, penum->TextBufferIndex * sizeof(float));
memcpy(penum->text_state->Advs, penum->Advs, penum->TextBufferIndex * sizeof(float));
+ memset(penum->text_state->GlyphWidths, 0x00, penum->TextBufferIndex * sizeof(float));
+ memcpy(penum->text_state->GlyphWidths, penum->GlyphWidths, penum->TextBufferIndex * sizeof(float));
+ memset(penum->text_state->SpanDeltaX, 0x00, penum->TextBufferIndex * sizeof(float));
+ memcpy(penum->text_state->SpanDeltaX, penum->SpanDeltaX, penum->TextBufferIndex * sizeof(float));
+ penum->text_state->FontName = (char *)gs_malloc(tdev->memory->stable_memory, 1,
+ font->font_name.size + 1, "txtwrite alloc font name");
+ if (!penum->text_state->FontName)
+ return gs_note_error(gs_error_VMerror);
+ memcpy(penum->text_state->FontName, font->font_name.chars, font->font_name.size);
+ penum->text_state->FontName[font->font_name.size] = 0x00;
unsorted_entry->Unicode_Text = (unsigned short *)gs_malloc(tdev->memory->stable_memory,
penum->TextBufferIndex, sizeof(unsigned short), "txtwrite alloc sorted text buffer");
@@ -2235,10 +1806,22 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
if (!unsorted_entry->Advs)
return gs_note_error(gs_error_VMerror);
+ unsorted_entry->GlyphWidths = (float *)gs_malloc(tdev->memory->stable_memory,
+ penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
+ if (!unsorted_entry->GlyphWidths)
+ return gs_note_error(gs_error_VMerror);
+ unsorted_entry->SpanDeltaX = (float *)gs_malloc(tdev->memory->stable_memory,
+ penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
+ if (!unsorted_entry->SpanDeltaX)
+ return gs_note_error(gs_error_VMerror);
memset(unsorted_entry->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
memcpy(unsorted_entry->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
memset(unsorted_entry->Advs, 0x00, penum->TextBufferIndex * sizeof(float));
memcpy(unsorted_entry->Advs, penum->Advs, penum->TextBufferIndex * sizeof(float));
+ memset(unsorted_entry->GlyphWidths, 0x00, penum->TextBufferIndex * sizeof(float));
+ memcpy(unsorted_entry->GlyphWidths, penum->GlyphWidths, penum->TextBufferIndex * sizeof(float));
+ memset(unsorted_entry->SpanDeltaX, 0x00, penum->TextBufferIndex * sizeof(float));
+ memcpy(unsorted_entry->SpanDeltaX, penum->SpanDeltaX, penum->TextBufferIndex * sizeof(float));
unsorted_entry->FontName = (char *)gs_malloc(tdev->memory->stable_memory,
(strlen(penum->text_state->FontName) + 1), sizeof(unsigned char), "txtwrite alloc sorted text buffer");
@@ -2287,7 +1870,7 @@ textw_text_process(gs_text_enum_t *pte)
code = gx_default_text_restore_state(pte_fallback);
if (code < 0)
return code;
- gs_text_release(pte_fallback, "txtwrite_text_process");
+ gs_text_release(NULL, pte_fallback, "txtwrite_text_process");
}
pte_fallback = penum->pte_fallback = NULL;
@@ -2311,6 +1894,14 @@ textw_text_process(gs_text_enum_t *pte)
pte->text.size * 4, sizeof(float), "txtwrite temporary advs array");
if (!penum->Advs)
return gs_note_error(gs_error_VMerror);
+ penum->GlyphWidths = (float *)gs_malloc(tdev->memory->stable_memory,
+ pte->text.size * 4, sizeof(float), "txtwrite temporary glyphwidths array");
+ if (!penum->GlyphWidths)
+ return gs_note_error(gs_error_VMerror);
+ penum->SpanDeltaX = (float *)gs_malloc(tdev->memory->stable_memory,
+ pte->text.size * 4, sizeof(float), "txtwrite temporary spandeltax array");
+ if (!penum->SpanDeltaX)
+ return gs_note_error(gs_error_VMerror);
}
{
switch (font->FontType) {
@@ -2378,7 +1969,7 @@ textw_text_process(gs_text_enum_t *pte)
penum->returned.current_glyph = pte_fallback->returned.current_glyph;
return code;
}
- gs_text_release(pte_fallback, "txtwrite_text_process");
+ gs_text_release(NULL, pte_fallback, "txtwrite_text_process");
penum->pte_fallback = 0;
}
}
@@ -2446,14 +2037,29 @@ textw_text_release(gs_text_enum_t *pte, client_name_t cname)
gs_free(tdev->memory, penum->TextBuffer, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
if (penum->Widths)
gs_free(tdev->memory, penum->Widths, sizeof(float), pte->text.size, "txtwrite free temporary widths array");
+ if (penum->Advs)
+ gs_free(tdev->memory, penum->Advs, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
+ if (penum->GlyphWidths)
+ gs_free(tdev->memory, penum->GlyphWidths, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
+ if (penum->SpanDeltaX)
+ gs_free(tdev->memory, penum->SpanDeltaX, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
/* If this is copied away when we complete the text enumeration succesfully, then
* we set the pointer to NULL, if we get here with it non-NULL , then there was
* an error.
*/
- if (penum->text_state)
+ if (penum->text_state) {
+ if (penum->text_state->Widths)
+ gs_free(tdev->memory, penum->text_state->Widths, sizeof(float), pte->text.size, "txtwrite free temporary widths array");
+ if (penum->text_state->Advs)
+ gs_free(tdev->memory, penum->text_state->Advs, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
+ if (penum->text_state->GlyphWidths)
+ gs_free(tdev->memory, penum->text_state->GlyphWidths, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
+ if (penum->text_state->SpanDeltaX)
+ gs_free(tdev->memory, penum->text_state->SpanDeltaX, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer");
+ if (penum->text_state->FontName)
+ gs_free(tdev->memory, penum->text_state->FontName, 1, penum->TextBufferIndex, "txtwrite free temporary font name copy");
gs_free(tdev->memory, penum->text_state, 1, sizeof(penum->text_state), "txtwrite free text state");
-
- gs_text_release(pte, cname);
+ }
}
/* This is the list of methods for the text enumerator */