Issue 100373 - Textshapes in Metafiles render wrong if systems have different fonts
Summary: Textshapes in Metafiles render wrong if systems have different fonts
Status: CLOSED FIXED
Alias: None
Product: Draw
Classification: Application
Component: viewing (show other issues)
Version: OOO310m5
Hardware: All Unix, all
: P3 Trivial (vote)
Target Milestone: OOo 3.1
Assignee: michael.ruess
QA Contact: issues@graphics
URL:
Keywords: regression
Depends on:
Blocks: 95768
  Show dependency tree
 
Reported: 2009-03-19 18:16 UTC by IngridvdM
Modified: 2009-04-21 11:38 UTC (History)
6 users (show)

See Also:
Issue Type: DEFECT
Latest Confirmation in: ---
Developer Difficulty: ---


Attachments
exmple showing the problem (24.60 KB, application/vnd.oasis.opendocument.spreadsheet)
2009-03-19 18:18 UTC, IngridvdM
no flags Details

Note You need to log in before you can comment on or make changes to this issue.
Description IngridvdM 2009-03-19 18:16:26 UTC
Load the attached document on a windows system. You can see that the font of
several texts look broken: 'Fruits, Apple, Banana, Ananas, a text shape in a
Writer OLE'.
All those are text shapes within an OLE object. For the OLE objects meta files
are created on save and displayed on load. The file was create on Linux with
OOO310m6. Same problem exists also if the file is created on Solaris.
Activating the OLE object and refreshing the metafile creates a correct display
on windows.
So there seems to be missing some information within the meta file when they are
saved on unix.
Comment 1 IngridvdM 2009-03-19 18:18:21 UTC
Created attachment 61054 [details]
exmple showing the problem
Comment 2 philipp.lohmann 2009-03-19 20:12:57 UTC
pl->hw,hdu: could you please have a look ?
Comment 3 Armin Le Grand 2009-03-20 12:20:28 UTC
AW->HDU: All of this happens in VCL and has to do with fonts, Primitives are not
involved when plyaing a MetaFile. Please have a look.
Comment 4 hdu@apache.org 2009-03-20 13:30:09 UTC
The problem is a combination of
1. the stupid legacy concept of a "font's average charwidth", which could almost be considered  to be a 
font-specific random number
2. OLE previews  seem to export any font-stretching not by a font-stretch factor (e.g. 120%), but by the 
font-specific random number multiplied by that stretching factor (e.g. NimbusL.avgcharwidth*120%)
3. different platforms have different fonts. E.g. NimbusSansL which is often available on Unix systems is 
rarely available on Mac or Windows), so the random font-specific numbers would not match. The font-
stretch-factor as the ratio of the written-avgcharwidth and the usedfont-avgcharwidth would be off by 
the difference of the font-specific random numbers.

So the central root cause is item 2: don't depend on arithmetic with random numbers if you need 
consistent results. The solution would be easy by explicitly writing out the font-stretch-factor instead 
of the bogus stretchfactor*random value, but this has problems with backwards compatibility.

@iha,aw.sj: For unstretched fonts such as in the attached document the solution would be quite easy 
though: just request the "default-font-width" for unstretched fonts during the metafile export! The 
"regression" probably comes from the fact, that the new drawing layer is much more accurate and so 
even factors of 100.0001% get the "stretched font treatment", which has the problem with random-
numbers of the legacy metafiles outlined above.

If the above suggestion (request default-width for is done then most of the problem is solved. The 
remainder of this issue would to extend the old metafile format to use font-stretch-factors instead of 
the insane multiplication product. Since the drawinglayer rework aims to replace the legacy metafiles by 
a much better approach based on drawing primitives (which on my advice avoid the random width 
number to calculate stretch factors) this remaining task to extend the legacy metafile will become 
redundant soon.
Comment 5 Armin Le Grand 2009-03-20 13:40:38 UTC
>@iha,aw.sj: For unstretched fonts such as in the attached document the solution
>would be quite easy though: just request the "default-font-width" for 
>unstretched fonts during the metafile export!

I see no way to easily do this. MetaFiles are recorded by using multiple calls
to OutputDevice. At least it needs to be done in VCL then.

>The "regression" probably comes
>from the fact, that the new drawing layer is much more accurate and so 
>even factors of 100.0001% get the "stretched font treatment", which has the 
>problem with random-numbers of the legacy metafiles outlined above.

No, for MetaFile replay, the primitives are not used, but still the VCL MetaFile
Play command. Primitives are currently not involved in MetaFile replay.

>If the above suggestion (request default-width for is done then most of the 
>problem is solved. The remainder of this issue would to extend the old 
>metafile format to use font-stretch-factors instead of the insane 
>multiplication product. Since the drawinglayer rework aims to replace the
>legacy metafiles by a much better approach based on drawing primitives (which
>on my advice avoid the random width number to calculate stretch factors) this
>remaining task to extend the legacy metafile will become redundant soon.

The primitive solution will in one of the next steps no longer use VCLs Play()
command for MetaFiles, but interpret the MetaFile and change it to primitives,
but this also requires the correct information in the MetaFiles themselves.
Also, for OLE, only for own OLEs (Chart) it would be possible to change geometry
transfer to primitives, so we will keep the MetaFile for OLEs for a long time.
Thus i see no way around fixing this in the current MetaFile first. It will not
be redundant, but necessary even for the future.
Comment 6 hdu@apache.org 2009-03-20 13:55:35 UTC
> I see no way to easily do this. MetaFiles are recorded by using multiple calls to OutputDevice.
> At least it needs to be done in VCL then.

If the layers above VCL cannot possibly remember that a font was intended to be unstretched then VCL 
could indeed try to guess that intention by using a heuristic and update the metafile on the fly while 
writing. This approach would be better than the current situation but not as good as getting the correct 
information. Reassigning the issue back to implement this second best solution, unless it show that the 
better solution I outlined in my other comment is not so difficult after all.
Comment 7 Armin Le Grand 2009-03-20 14:13:12 UTC
>If the layers above VCL cannot possibly remember that a font was intended to be
>unstretched then VCL could indeed try to guess that intention by using a 
>heuristic and update the metafile on the fly while writing.

The Layers above VCL are external Applications for OLE. I see no way how they
should remember that. I also do not see how this should help when WE need to
play the MetaFile. I also see no reason for guessing.

Does the MetaFile action created when calling DrawText() not contain all
necessary information to record the current text output and to replay it? If
Yes, why is it going wrong? If not, this is a design error (maybe not in our
MetaFile, but in mtf as file format (?).

At least fo our MetaFiles we should somehow add that needed information to the
MetaFiles then; maybe in a MetaFileComment, as we already do with other infos.
This would at least solve the problem for MetaFiles we created ourselves (and
would be backward compatible, too). Shouldn't that be the fix to do...?
Comment 8 hdu@apache.org 2009-03-20 14:40:52 UTC
> Does the MetaFile action created when calling DrawText() not contain all necessary information
> to record the current text output and to replay it?

No, as long as the font-specific random number is involved only the exactly same system and its 
relatives can replay it exactly.

> If not, this is a design error (maybe not in our MetaFile, but in mtf as file format)

Yes. The problem with fixing it is that the error is so old and got into binary files. Currently this part of 
metafiles cannot be replayed reliably.

> At least fo our MetaFiles we should somehow add that needed information to the
> MetaFiles then; maybe in a MetaFileComment, as we already do with other infos

That's probably the best solution: It will improve the cross-system compatibility and not make things 
worse from a backwards compatibility aspect.
Comment 9 hdu@apache.org 2009-03-27 15:18:51 UTC
reassigning for now as discussed
Comment 10 Armin Le Grand 2009-03-30 10:07:24 UTC
AW: I will check some aspects and look for an easy solution, but i have to make
clear that i'm not the MetaFile expert and only take over currently since HDU is
on vacation. Taking a look...
Comment 11 Armin Le Grand 2009-03-30 10:19:57 UTC
AW: Annotation to the "regression" keyword and 'broken' Flag: This behaviour
exists since we have MetaFiles on different systems, so this is in no way 3.1
specific, but exists in all former versions.
Comment 12 thorsten.ziehm 2009-03-30 13:15:19 UTC
Perhaps the problem is old, but the effect in 3.1 is new. It isn't possible to
share documents with OLE objects between UNIX and Windows anymore, because the
font is broken on Windows systems. This wasn't in OOo 3.0.1 and older versions.
As I wrote the consequence of this bug is worst in 3.1. I set this bug to 3.1
target and will announce it as showstopper, because it isn't possible anymore to
share documents platform independently. This is broken in 3.1. 
Comment 13 Armin Le Grand 2009-03-30 13:31:19 UTC
AW: I have a pretty simple, working fix which i checked in different scenarios.
Basic problem is that the Fonts streamed to the MetaFiles when creating the OLE
contents is slightly different for WIN32 nad other systems. On WIN32, the
definition for not scaled fonts is that FontWidth == 0, while on all other
systems this definition and Width == Height are allowed. This means that
definitions when using them in WIN32 need to be either also interpreted using
both definitions or to be corrected.

When correcting the Font import (which is uded on MetaFile read) in font.cxx

SvStream& operator>>( SvStream& rIStm, Impl_Font& rImpl_Font )

using

#ifdef WIN32
    // #i100373# handle font scaling for WIN32
    //
    // When width and height are identical and we are on a windows system,
    // translate the width to zero to express that the font is not to be
    // scaled at all. The width == height definition was probably created
    // by another Linux- or Mac-based system, but will be interpreted
    // different on WIN32 systems, thus this correction on import is
    // necessary
    if(rImpl_Font.maSize.getWidth() == rImpl_Font.maSize.getHeight())
    {
        rImpl_Font.maSize.setWidth(0);
    }
#endif

after the line

    rIStm >> rImpl_Font.maSize;

this difference gets corrected and the visualisation works as expected. The
advantage is that this solution does not change the current MetaFile format or
it's creation, but only corrects the import, so all already written files will work.

The better solution would be to have a unique definition for non-scaled fonts in
WIN32 and all other systems. This means to interpret Width==Height as non-scaled
on WIN32, too. It would be hard to ensure this, there may be several places in
VCL involved (HDU would know).

AW->PL: Do You see any caveats with such a solution? I checked WIN32- and
Linux-created MetaFiles, viewed on WIN32 and Linux, all seems to work well.
Comment 14 Armin Le Grand 2009-03-30 13:37:34 UTC
AW->TZ: I loaded the bugdoc with a 3.0, and it looks exactly the same (wrong) as
in a OOO310. I have not checked with a 3.0.1 yet.
I do not mention this to state that we will not fix it (it should have been
fixed in former versions already), but to show my surprise about the regression
and broken flag usage here. Else i would have changed those flags.
Comment 15 Armin Le Grand 2009-03-30 14:35:58 UTC
AW: Oops, forgot to add PL to discussion...
Comment 16 philipp.lohmann 2009-03-30 15:07:33 UTC
@aw: depending on who else uses the stream operator this might invent some
strange compatibility issues (e.g. I don't know how fonts came into the binary
formats). Moreover: how do you distinguish the unstretched case from the case
where the font is stretched and the stretched width matches the font height ?
Comment 17 thorsten.ziehm 2009-03-30 15:11:38 UTC
=>AW: That is correct, that the attached file looks broken in 3.0 and 3.0.1. But
you couldn't _create_ such broken files in 3.0 and 3.0.1. Therefore I do not
know if it is correct to fix the import. Because the creation of such files is
the problem. And when you fix the import in 3.1 you can create such broken files
which looks ugly in versions lower than 3.1.
Comment 18 Armin Le Grand 2009-03-30 15:48:48 UTC
AW->TZ: That is a very (if not the) important hint. Thus the export did somehow
change. For some reason width==height non-scaled Font definitions are now
created in the MetaFiles. I will check for this now.

AW->PL: I think noone else uses the stream operator. For the how do you
distinguish question: You cannot. That's a problem with the existing definitions
HDU is aware of (that whole area needs rework IMHO).
Comment 19 Armin Le Grand 2009-03-30 16:37:16 UTC
AW: Cheched MetaFile creation. In
VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D a VCL Font is
created by default using a width==height definition (as HDU suggested as better
definition). This is corrected in the method actually for WIN32 to start with
width==0 for internal use, but not for non-WIN32 systems.

Thus, non-WIN32 systems will write MetaFiles containing the width==height
non-font-scaling definition. When these are loaded on WIN32-system, we have a
usage of a Font-definition not correct for the current system.

This could be corrected by import, but not for existing offices. So it needs to
be corrected
(1) at font creation time, or
(2) at MetaFile export time.

(1) will fix the problem and use the 0==width definition for all systems, thus
also creating the correct MetaFiles, but internally use the less good definition
even for systems which support width==height

(2) will guarantee compatible MetaFiles for all existing offices (3.0, etc.). It
would need to be applied to all Font event exports where width==height in the
font definition.

Both will work, whereby (2) seems even to be more secure since the same MetaFile
definitions as previously are forced to be created, independent from the
MetaFile source. OTOH (1) works well and is closer on what the VCL-users (old
DoPaintObject implementations) did.

Mayne (1) and (2) should be done to ensure correct MetaFile creations even when
(1) should be reworked/changed again internally.
Comment 20 Armin Le Grand 2009-03-31 10:28:01 UTC
AW: Experimented with (1) and (2), creating CWS aw068 for this task. I will use
(1), also checked for streched text support on all systems and in-between
systems using MetaFiles.
Comment 21 Armin Le Grand 2009-03-31 10:50:33 UTC
AW: Made and commented change in drawinglayer, builds running. Checked on
unxlngi6.pro already, with streched text, too. Waiting for wntmsci12.pro version
to re-check result.
Comment 22 Armin Le Grand 2009-03-31 11:20:26 UTC
AW: Done, fixed. All installsets here.
Comment 23 Armin Le Grand 2009-03-31 11:24:07 UTC
AW->MRU: To test, You need in principle create OLEs with a non-WIN32 version and
load in the WIN32-version. Easiest way to do that:
- Load BugDoc with non-WIN32 version (e.g. unxlngi6.pro)
- Activate all OLEs once, evtl. add streched tex shape
- save with another name
- load new doc with WIN32 installation
-> looks good now. Formally all fonts in OLEs were streched wrongly.
Comment 24 michael.ruess 2009-04-01 09:45:54 UTC
Verified in CWS aw068.
Comment 25 michael.ruess 2009-04-21 11:38:16 UTC
Checked in OOO310m10.