diff options
author | Paul Gardiner <paul@glidos.net> | 2012-04-09 13:28:49 +0100 |
---|---|---|
committer | Paul Gardiner <paul@glidos.net> | 2012-05-08 15:07:39 +0100 |
commit | 7eebd3b6d6f3287ce642ff7e1be9cafc5cfe329f (patch) | |
tree | a507562c44da560ecf14f7ae3a9c88fb5ffbe8c4 /pdf/pdf_form.c | |
parent | 2aff7f90f0c2f60406b2854d1bea2217b44b78e1 (diff) | |
download | mupdf-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.c | 35 |
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); } } } |