Cairofying VisualWorks

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Cairofying VisualWorks

Joachim Geidel
A little while ago, I published CairoGraphics-Wrappers to the public
repository. It demonstrates that it's possible to write a compatibility
layer for VisualWorks for rendering a VisualComponent using the Cairo
graphics library instead of the graphics primitives built into the
virtual machine, while still using the current protocol of
GraphicsContext. Just wrap the component in a CairoWrapper, and you are
done (almost...).

But how about switching to Cairo completely? CairoGraphics-Windows in
the public repository explores this possibility. While the package
CairoGraphics-Wrappers implements the basic compatibility layer and a
CairoWrapper which can be used to render a single component of a Window
with Cairo, CairoGraphics-Windows lets you render the complete contents
of an arbitrary Window with Cairo. There are several ways to enable
Cairo output for a Window:

* Override ApplicationModel>>usesCairoGraphics to answer true. If the
ApplicationModel is the application of an ApplicationWindow or the model
of a ScheduledWindow or ApplicationWindow, the window will create a
CairoGraphicsContext in its graphicsContext method, send renderOn:
instead of displayOn: to its component, and send renderDamageList:in:
instead of displayDamageList:in: to its damageRepairPolicy.

* For ScheduledWindows with a model which is not an ApplicationModel,
implement usesCairoGraphics in the model's class such that it answers true.

* If you want to know how far you can go, evaluate
        CairoGraphics.UseCairoForAllWindows := true.
Save your image before doing this!

Does it work? Yes and no, of course. :-) The attached screenshot shows a
RefactoringBrowser and a Menu rendered with Cairo. You may notice some
differences from the normal output. Most of them are due to differences
in the interpretation of coordinates in Cairo and the VisualWorks VM,
others are due to the fact that I left some work for other people. ;-)

The results of the experiment:

* The changes needed for making a widget work with Cairo - if there are
any at all - are quite small if one uses CairoGraphics-Wrappers. In most
cases, it means replacing "aGraphicsContext copy" by "aGraphicsContext
saveWhile: [...]". See CairoGraphics-Widgets for examples.

* There is work to do for fine-tuning the output of thin lines e.g. in
tree views, menu separators, borders etc.

* ComposedTextView and its subclasses need work. The output of text
seems to work, but text selection leads to incorrect output (parts of
the text disappear). Options are implementing new widgets based on
Pango, or adding new rendering and text measuring methods to the current
widgets (which may be hard).

* On Windows, Cairo raises exceptions with an "out of memory" message
relatively often. This can only be cured by closing the offending window
or switching Cairo output off. As far as I understand, the errors don't
have anything to do with memory consumption, but with GDI errors. Travis
might know more about it. Another problem which happens very often when
I use the examples in CairoGraphics-Wrappers-Examples is that after
closing a Cairo based window, the damage repair of a normal window which
has been covered by this window will run into a primitive failure in the
first graphics primitive executed (Windows XP SP2, VW 7.5, Cairo
1.4.10). These problems have to be solved. The second problem might also
be a bug in the VisualWorks VM which does not occur under normal
circumstances.

So, is it possible to switch to Cairo with reasonable effort?
IMHO, yes. Depending on what amount of money you define as reasonable,
of course. :-)

Joachim Geidel

----

PS: If you want to try it, you will need the Cairo libraries. On Fedora
and Debian based Linuxes, they should be installed by default.
Installation instructions for Linux, MacOS-X, and Windows are available
at http://www.cairographics.org/download/

For Windows, the best place to get the DLLs is
        http://www.gimp.org/%7Etml/gimp/win32/downloads.html
You need:
        libcairo-2.dll from cairo-1.4.10.zip
        libpng13.dll from libpng 1.2.8
        zlib1.dll from Zlib 1.2.3
Put them in the working directory or a directory which is in your PATH.

RBCairo.jpg (94K) Download Attachment