EMF export, unexpected text size change

Bug #965594 reported by David Mathog on 2012-03-26
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Inkscape
Undecided
Unassigned

Bug Description

Some SVG files when saved as an EMF produce an EMF file with some of the text resized. In the attached example the only
difference between the two boxed pieces of text is that the one on the left has been ungrouped and regrouped. When saved
as EMF the one on the left retains its point size, while the one on the right becomes smaller.

Observed both on 0.48.2 and trunk. On windows.

David Mathog (mathog) wrote :

Example, text in both boxes the same size in source.

David Mathog (mathog) wrote :

After export to EMF (no options checked) the text in one of the boxes changes sizes.

David Mathog (mathog) wrote :

Sorry, I do not know what steps were required to put the SVG into this state. When viewed in Inkscape the two text boxes
in the test svg look the same to me.

David Mathog (mathog) wrote :

Interesting. Looking at the XML, the one that acts oddly has a transform matrix a few levels up and specifies the small font size that ends up in the EMF. The one that acts normally has no transform matrix at the equivalent level and specifies
the size font that does end up in the EMF. Select the text in either one in inkscape and both show a font size of 18.51 px. So it looks like something in the EMF export is dropping the transform in the broken one, leaving the "naked" smaller font of 13.57 px.

Make a copy of the one that is acting strangely and ungroup it. The matrix transformation is then associated only with the rectangle, and the font size is changed to 18.5px. Regroup and the transformation stays associated with the rectangle, and the resultant "text in a box" works as expected.

That gives me a clue how to reproduce this problem. Testing..., yes, can reproduce problem reliably.

To make problem boxed text do the following.

1. Make large text (say 30px, the exact size does not matter)
2. Make a white rectangle with a black edge a little bigger than the text.
3. Put the text on the rectangle and group.
4. Resize by holding down control and shrinking the grouped object.

Result: in the inkscape drawing surface it looks right, but on save as to EMF the text will be the wrong size. In this case the
font will be too large. If the original text/box had been smaller, and then it was resized up, the final save would result in text that was too small.

As before, the problem text can be repaired by ungroup, and then regroup. This moves the transformation away from the text and associates it only with the rectangle. The end result is that text in the saved EMF is then the expected size.

David Mathog (mathog) wrote :

Found the problem. In emf-win32-print.cpp the line setting the font height was not using the scale factor from the transform. It sort of looks like it does because it references "font_size.computed" but that doesn't mean what I naively thought it did.

There is another complication - applications are very hit and miss about supporting nonuniform scaling of text. LibreOffice Draw can write an EMF file with text stretched differently by height and width, but neither PowerPoint nor Inkscape can currently read it that way. Both seem to drop the Width field back to 0 and keep only the height. For the moment I propose
that we continue to sweep this problem under the rug and only support uniformly scaled text imported/exported through the EMF file type.

I will attach some examples after this post that illustrate why the minimum scale was used.

For trunk, in the file emf-win32-print.cpp change:

        lf->lfHeight = -style->font_size.computed * IN_PER_PX * dwDPI;

to

        // Scale the text to the minimum stretch. (It tends to stay within bounding rectangles even if
        // it was streteched asymmetrically.) Few applications support text from EMF which is scaled
        // differently by height/width, so leave lfWidth alone.
        lf->lfHeight = -style->font_size.computed * IN_PER_PX * dwDPI * std::min(tf.expansionX(),tf.expansionY());;

Starting from my omnibus EMF patch (bug 988601) change:

        lf->lfHeight = -style->font_size.computed * PX2WORLD; //Penner

to

        // Scale the text to the minimum stretch. (It tends to stay within bounding rectangles even if
        // it was streteched asymmetrically.) Few applications support text from EMF which is scaled
        // differently by height/width, so leave lfWidth alone.
        lf->lfHeight = -style->font_size.computed * PX2WORLD * std::min(tf.expansionX(),tf.expansionY());

David Mathog (mathog) wrote :

The upper left example is the original. Below it are two examples that have been stretched/shrunk uniformly. Below that
are two examples which were scaled only by height or width. All of the examples were then rotated.

David Mathog (mathog) wrote :
David Mathog (mathog) wrote :

This is a screen shot of the EMF produced, as viewed with Windows Preview. The isotropically scaled examples look like they should. The anisotropically scaled examples do not match the originals, but they do stay within their surrounding rectangles. Had the patch used std::max instead of std::min in both cases the text would have extended outside of the rectangles. (Put simply, if the choice must be min or max, min looks better.)

David Mathog (mathog) wrote :

EMF example from LibreOffice draw which includes anisotropically stretched text.

David Mathog (mathog) wrote :

Screenshot of the previous example viewed in Windows Preview.

David Mathog (mathog) wrote :

Previous example after being opened in Inkscape. The width field is dropped and the final text size is determined solely by the height field. PowerPoint does the same thing when the "insert picture from file" is ungrouped. Before it is ungrouped it shows the text anisotropically stretched (ie, correctly).

jazzynico (jazzynico) on 2012-06-23
tags: added: emf exporting
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers