summaryrefslogtreecommitdiff
path: root/source/fitz/svg-device.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2014-02-04 10:33:14 +0000
committerRobin Watts <robin.watts@artifex.com>2014-02-04 14:06:52 +0000
commite80425cb7049c5c097d965e2236cfa751be6d522 (patch)
treec361cd816b4cfd9150eda133b0440909e973e526 /source/fitz/svg-device.c
parent210ae39dfb7c6793482d92af5b88d335e4ef5f31 (diff)
downloadmupdf-e80425cb7049c5c097d965e2236cfa751be6d522.tar.xz
Improve glyph bounding, outlining and SVG output text.
Luiz Henrique de Figueiredo reports that glyphs output from the SVG device contain 'lumpy' outlines. Investigation reveals that this is because the current code extracts the outlines from freetype at unit scale, and then relies on SVG to scale them up. Unfortunately, freetype insists on working in integer maths, so any sort of scaling runs the risk of distorting the outlines. The fix is to change the way we call freetype; we now request an 'UNSCALED' char, and set the required size to be the design size. We then transform the results in the floating point domain ourself. This cures the lumpy outlines, but reveals a second problem, namely that the bbox given for characters is inaccurate (and sometimes too small). Investigation shows that this is again caused by freetypes scaling, so we apply the same trick; ask for the glyph without scaling (as far as possible), and then scale the results down. We also take care to spot the 'ft_hint' flag in the font. If set this indicates that hinting must be performed to ensure that the returned outlines are sane. We therefore take note of this when calculating both bbox and outlines. This means that 'tricky' fonts such as dynalab ones now render correctly. This produces many changes in the bitmaps, the vast majority of which are neutral. The ones that aren't are all progressions.
Diffstat (limited to 'source/fitz/svg-device.c')
-rw-r--r--source/fitz/svg-device.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c
index aa5ff74c..c48c123d 100644
--- a/source/fitz/svg-device.c
+++ b/source/fitz/svg-device.c
@@ -312,7 +312,7 @@ svg_dev_text_as_paths_defs(fz_device *dev, fz_text *text, const fz_matrix *ctm)
fz_output *out = sdev->out;
int i, font_idx;
font *fnt;
- fz_matrix shift = { 1, 0, 0, 1, 0, 0};
+ fz_matrix shift = fz_identity;
for (font_idx = 0; font_idx < sdev->num_fonts; font_idx++)
{
@@ -360,20 +360,26 @@ svg_dev_text_as_paths_defs(fz_device *dev, fz_text *text, const fz_matrix *ctm)
/* Need to send this one */
fz_rect rect;
fz_path *path;
- fz_bound_glyph(ctx, text->font, gid, &fz_identity, &rect);
- shift.e = -rect.x0;
- shift.f = -rect.y0;
- out = start_def(sdev);
- fz_printf(out, "<symbol id=\"font_%x_%x\">", fnt->id, gid);
- path = fz_outline_glyph(sdev->ctx, text->font, gid, &shift);
+ path = fz_outline_glyph(sdev->ctx, text->font, gid, &fz_identity);
if (path)
{
+ fz_bound_path(ctx, path, NULL, &fz_identity, &rect);
+ shift.e = -rect.x0;
+ shift.f = -rect.y0;
+ fz_transform_path(ctx, path, &shift);
+ out = start_def(sdev);
+ fz_printf(out, "<symbol id=\"font_%x_%x\">", fnt->id, gid);
fz_printf(out, "<path");
svg_dev_path(sdev, path);
fz_printf(out, "/>\n");
}
else
{
+ fz_bound_glyph(ctx, text->font, gid, &fz_identity, &rect);
+ shift.e = -rect.x0;
+ shift.f = -rect.y0;
+ out = start_def(sdev);
+ fz_printf(out, "<symbol id=\"font_%x_%x\">", fnt->id, gid);
fz_run_t3_glyph(ctx, text->font, gid, &shift, dev);
}
fz_printf(out, "</symbol>");