Successful Print Preview


I have been wrestling with WebKit for some time trying to get a proper 'Print Preview' thumbnail. Unfortunately, my various attempts generally resulted in good looking text, but offset and strangely scaled graphical elements, or vice versa.

During this process I learned that Windows (or specifically, MFC) implements a print preview by generating a device context for the selected printer, and a 'sister' display context that is configured to mimic the printed surface such that drawing commands intended for the full-sized printer surface are rendered into a small preview display.

This is accomplished by setting the mapping mode of the display context to MM_ANISOTROPIC, and setting a Window Extent (for the full size of the printed page) and a View Extent for the size of the display.

Unfortunately, if you pass a context created with these kinds of settings to Cairo, it improperly scales textual elements. In the attached image you can see that text written with cairo_show_text and cairo_show_glyphs get drawn at the same size no matter how the context is scaled. Text written with cairo_text_path and other graphical elements (e.g., the arc in the example) are scaled properly.

Thankfully, there is a workaround. After writing a test program to illustrate the issue, I discovered through some trial and error that everything works fine if I reset the preview window mapping mode to MM_TEXT, reset the HDC's WorldTransform to unity, and set the Cairo context's CTM to be scaled to match the ratio of the Viewport Extents to the Window Extents.

Voila! Properly scaled previews.

This change is implemented in Bug 39329, which will hopefully be committed to the archive soon.

Comments

Popular Posts