summaryrefslogtreecommitdiff
path: root/pdf/pdf_form.c
diff options
context:
space:
mode:
authorPaul Gardiner <paul@glidos.net>2012-04-09 13:28:49 +0100
committerPaul Gardiner <paul@glidos.net>2012-05-08 15:07:39 +0100
commit7eebd3b6d6f3287ce642ff7e1be9cafc5cfe329f (patch)
treea507562c44da560ecf14f7ae3a9c88fb5ffbe8c4 /pdf/pdf_form.c
parent2aff7f90f0c2f60406b2854d1bea2217b44b78e1 (diff)
downloadmupdf-7eebd3b6d6f3287ce642ff7e1be9cafc5cfe329f.tar.xz
Forms: use a text matrix to fit text rather than altering the font size
To achieve sufficient accuracy, non-integer font sizes were being used, which MuPDF can handle, but may be illegal. The text matrix is the better method.
Diffstat (limited to 'pdf/pdf_form.c')
-rw-r--r--pdf/pdf_form.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/pdf/pdf_form.c b/pdf/pdf_form.c
index aec11a09..e7e5caec 100644
--- a/pdf/pdf_form.c
+++ b/pdf/pdf_form.c
@@ -153,7 +153,7 @@ static int read_font_size_from_da(fz_context *ctx, char *da)
return fontsize;
}
-static void copy_da_with_altered_size(fz_context *ctx, fz_buffer *fzbuf, char *da, float size)
+static void copy_da_with_altered_size(fz_context *ctx, fz_buffer *fzbuf, char *da, int size)
{
int tok;
pdf_lexbuf lbuf;
@@ -171,7 +171,7 @@ static void copy_da_with_altered_size(fz_context *ctx, fz_buffer *fzbuf, char *d
if (last_tok_was_int)
{
if (tok == PDF_TOK_KEYWORD && !strcmp(lbuf.scratch, "Tf"))
- fz_buffer_printf(ctx, fzbuf, " %1.2f", size);
+ fz_buffer_printf(ctx, fzbuf, " %d", size);
else
fz_buffer_printf(ctx, fzbuf, " %d", last_int_tok_val);
@@ -223,7 +223,7 @@ static fz_bbox measure_text(pdf_document *doc, pdf_obj *dr, fz_buffer *fzbuf)
return bbox;
}
-static fz_buffer *create_text_buffer(fz_context *ctx, fz_rect *clip, char *da, float fontsize, float x, float y, char *text)
+static fz_buffer *create_text_buffer(fz_context *ctx, fz_rect *clip, char *da, int fontsize, fz_matrix *tm, char *text)
{
fz_buffer *fzbuf = fz_new_buffer(ctx, 0);
const char *fmtstart =
@@ -236,7 +236,7 @@ static fz_buffer *create_text_buffer(fz_context *ctx, fz_rect *clip, char *da, f
const char *fmtbtxt =
" BT";
const char *fmttxt =
- " %1.2f %1.2f Td"
+ " %1.2f %1.2f %1.2f %1.2f %1.2f %1.2f Tm"
" (%s) Tj"
" ET"
" Q"
@@ -248,11 +248,11 @@ static fz_buffer *create_text_buffer(fz_context *ctx, fz_rect *clip, char *da, f
if (clip)
fz_buffer_printf(ctx, fzbuf, fmtclip, clip->x0, clip->y0, clip->x1 - clip->x0, clip->y1 - clip->y0);
fz_buffer_printf(ctx, fzbuf, fmtbtxt);
- if (fontsize < 0.0)
+ if (fontsize < 0)
fz_buffer_printf(ctx, fzbuf, " %s", da); /* Copy da unchanged */
else
copy_da_with_altered_size(ctx, fzbuf, da, fontsize);
- fz_buffer_printf(ctx, fzbuf, fmttxt, x, y, text);
+ fz_buffer_printf(ctx, fzbuf, fmttxt, tm->a, tm->b, tm->c, tm->d, tm->e, tm->f, text);
}
fz_catch(ctx)
{
@@ -280,7 +280,7 @@ static void measure_ascent_descent(pdf_document *doc, pdf_obj *dr, char *da, cha
strcpy(testtext, "My");
strcat(testtext, text);
/* Use large font size for increased accuracy */
- fzbuf = create_text_buffer(ctx, NULL, da, 100, 0, 0, testtext);
+ fzbuf = create_text_buffer(ctx, NULL, da, 100, &fz_identity, testtext);
bbox = measure_text(doc, dr, fzbuf);
*descent = -bbox.y0 / 100.0;
*ascent = bbox.y1 / 100.0;
@@ -299,7 +299,8 @@ static void measure_ascent_descent(pdf_document *doc, pdf_obj *dr, char *da, cha
fz_buffer *create_text_appearance(pdf_document *doc, fz_rect *bbox, pdf_obj *dr, char *da, char *text)
{
fz_context *ctx = doc->ctx;
- float height, width, fontsize;
+ int fontsize;
+ float height, width;
fz_buffer *fzbuf = NULL;
fz_rect rect;
fz_bbox tbox;
@@ -320,17 +321,22 @@ fz_buffer *create_text_appearance(pdf_document *doc, fz_rect *bbox, pdf_obj *dr,
fz_try(ctx)
{
float ascent, descent;
+ fz_matrix tm = fz_identity;
measure_ascent_descent(doc, dr, da, text, &ascent, &descent);
fontsize = read_font_size_from_da(ctx, da);
if (fontsize)
{
- fzbuf = create_text_buffer(ctx, &rect, da, -1.0, 2.0, 2.0 + fontsize * descent, text);
+ tm.e = 2.0;
+ tm.f = 2.0 + fontsize * descent;
+ fzbuf = create_text_buffer(ctx, &rect, da, -1.0, &tm, text);
}
else
{
- fontsize = height;
- fzbuf = create_text_buffer(ctx, &rect, da, fontsize, 2.0, 2.0 + height * descent, text);
+ fontsize = floor(height);
+ tm.e = 2.0;
+ tm.f = 2.0 + fontsize * descent;
+ fzbuf = create_text_buffer(ctx, &rect, da, fontsize, &tm, text);
tbox = measure_text(doc, dr, fzbuf);
if (tbox.x1 - tbox.x0 > width)
@@ -338,9 +344,10 @@ fz_buffer *create_text_appearance(pdf_document *doc, fz_rect *bbox, pdf_obj *dr,
/* Text doesn't fit. Regenerate with a calculated font size */
fz_drop_buffer(ctx, fzbuf);
fzbuf = NULL;
- fontsize = height * width / (tbox.x1 - tbox.x0);
- /* Use the same offset to keep the baseline constant */
- fzbuf = create_text_buffer(ctx, &rect, da, fontsize, 2.0, 2.0 + height * descent, text);
+ /* Scale the text to fit but use the same offset
+ * to keep the baseline constant */
+ tm.a = tm.d = width / (tbox.x1 - tbox.x0);
+ fzbuf = create_text_buffer(ctx, &rect, da, fontsize, &tm, text);
}
}
}