Mixed clipping using printing surfaces to windows metafiles
Submitted by Zoltan Turanyi
Assigned to cairo-bugs mailing list
Description
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.)
Version: 1.8.8