Bug 25893

Summary: Mixed clipping using printing surfaces to windows metafiles
Product: cairo Reporter: Zoltan Turanyi <teknos>
Component: win32 backendAssignee: cairo-bugs mailing list <cairo-bugs>
Status: RESOLVED MOVED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: normal    
Priority: medium    
Version: 1.8.8   
Hardware: x86 (IA32)   
OS: Windows (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: The windows metafile containing erroneous input
A PNG rendering of the other attachment, showing the problem.

Description Zoltan Turanyi 2010-01-04 09:54:08 UTC
Printing surfaces query the initial clip box of the device context upon creation. This is used as the extent of the surface later on.
This mechanism causes problems, when the device context is a metafile DC. Some drawing operations are automatically clipped to the surface extent (I have seen font output or image fallback doing so), but some other drawing operations are not (such as lines, for example). This is inconsistent and should not happen on my view. I think clipping (even if based on extents) should apply equally to all operations.

How to reproduce
----------------
HDC hdc = CreateEnhMetaFile(NULL, "test.emf", NULL, NULL);
surface = cairo_win32_printing_surface_create(hdc);
cr = cairo_create(surface);
cairo_move_to(cr, 0, 0);
cairo_line_to(cr, 10000, 10000); //bigger than screen
cairo_stroke(cr);
cairo_move_to(cr, 10000, 10000);
cairo_show_text(cr, "This will not be visible using a truetype font");
cairo_destroy (cr);
cairo_surface_show_page(surface);
cairo_surface_destroy (surface);
CloseEnhMetaFile(hdc);

My opinion
----------
The problem is difficult to circumvent. Since most windows metafiles are created using a copy of the screen device context as reference context, the initial clip box is essentially the max size of the display device. It would be nice to support metafiles created this way. I could not change this initial clipping box from the device context before creating the cairo surface, so the freshly created surface will always have the extent of the display device. An alternative would be to use a different device context as reference DC when creating the metafile - but I think obtaining a printing DC is complicated and not so ubiquitous as not all systems have a printer installed.

I think cairo should somehow check if the device context is a windows metafile and treat such printing surfaces as unbounded, if possible. If not then maybe asking for explicit extent could be an alternative.

I think this mechanism is still there in 1.9.4.

An additional comment/very related feature request. All the above is relevant for Enhanced Metafiles (EMF). Cairo does not seem work with DCs created from old-format windows metafiles (WMF). I think this is partially to the fact that those do not have an initial clipping region and when cairo queries the initial clip in _cairo_win32_save_initial_clip(), the call fails and no surface is created. There may be other GDI calls that do not work for old-format metafiles, but if not then maybe this limitation should be lifted, so that cairo can draw directly to old-format metafiles. (EMF to WMF conversion does not work that fine, so having a direct WMF output is better. WMF output is needed for OLE, since OLE unfortunately does not support EMF.)
Comment 1 Zoltan Turanyi 2010-06-14 07:41:50 UTC
Created attachment 36265 [details]
The windows metafile containing erroneous input

You can view this file by inserting it into any Microsoft office tool (probably openoffice on Windows, too).
Comment 2 Zoltan Turanyi 2010-06-14 07:44:01 UTC
Created attachment 36266 [details]
A PNG rendering of the other attachment, showing the problem.

This image is a rendering of the windows metafile (other attachment). The black stripes on the side are not part of the image, and also a white border is added, but you can still see the general idea: text is clipped, but lines are not.
Comment 3 Zoltan Turanyi 2010-06-14 07:45:23 UTC
Please let me know if I shall try to come up with a patch - I am not sure what is the way of working here. It would help me to have this fixed in the upcoming release.
Comment 4 GitLab Migration User 2018-08-25 13:30:56 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/cairo/cairo/issues/43.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.