Wednesday, July 29, 2009

How to Use Foxit PDF Reader 3.0 on Ubuntu 8.04 under Wine

I figured out how to set up and run Foxit PDF Reader on Ubuntu 8.04 a little while ago, and I'm just now writing it down. Foxit works extraordinarily well under Wine: displaying documents, editing PDF form fields, annotating documents, and printing to a USB printer all worked for me out of the box. There are certain tricky things involved in setting it up, though, hence this How To blog post.

First, download Foxit. The Foxit Windows installer didn't work for me, but fortunately Foxit offers a .zip which contains the application frozen into a single Windows executable. Here's a direct link at the time of this writing: http://mirrors.foxitsoftware.com/pub/foxit/reader/desktop/win/3.x/3.0/enu/FoxitReader30_enu.zip

Unzip the executable and put it somewhere in your home directory where it won't be touched, for example, ~/apps/.

You're now going to make a small shell script to run Foxit under Wine. Copy the following text into a file on your PATH, and make the file executable. I put it in /usr/bin/foxit.


#!/bin/sh

#got code to test whether path is absolute, here:
#http://www.unix.com/shell-programming-scripting/38018-test-whether-absolute-path-variable.html

PATH_TO_FOXIT="/home/jacob/apps/Foxit Reader.exe"

case $1 in
/*) absolute=1 ;;
*) absolute=0 ;;
esac

if [ "$absolute" = "1" ]; then
#we assume that root is mounted at Z: as is default on most wine distro
wine "$PATH_TO_FOXIT" "Z:/$1"
else
wine "$PATH_TO_FOXIT" "$1"
fi


This shell script is smart enough that it will actually take arguments that you pass to it on the command line, and pass it into the Foxit executable. This makes it possible open a PDF in Foxit from the command line, e.g.

jacob@jacob-laptop:~$ foxit Documents/Research/papers_to_read/MDAUML.pdf &


You should now be able to open PDF's in Nautilus by right-clicking the PDF and choosing Open With -> Open With Other Application -> Use a Custom Command -> {type in "/usr/bin/foxit" and click "Open"}. PDF files should now open automatically in Foxit when you open them from Nautilus.

Finally, you can configure Firefox to open PDF's in Foxit whenever you download a new PDF. Just go to Edit -> Preferences -> Applications -> {type "pdf" into the search bar} -> {under the dropdown menu, select "Use other ..."} -> {select file "/usr/bin/foxit" and click "Open"}. Note that this doesn't fully change the default PDF reader for Firefox, as, for example, when you open a PDF from the Download dialog, it will still open in Evince, the GNOME default. I, unfortunately, haven't found a way to change this behaviour, and I'd be very grateful for any comments anyone might have on this.

Saturday, July 25, 2009

SVG Development with GWT 1

In order for me to fulfill my project's goal of implementing the retained-mode graphics API of Draw2d in terms of the retained-mode API of SVG, I need to be able to develop SVG using GWT. I remain confident that this is feasible, but it has been nontrivial to set up.

I was originally going to use a GWT library called Tatami, the role of which is to expose much of the functionality of the Dojo JavaScript toolkit to Java, including the excellent, cross-browser dojox.gfx retained-mode graphics API. Unfortunately, Tatami turned out to be unsuitable right out of the gate, as its graphics API does not allow the developer to assign event listeners to individual objects, only to the top-level canvas. I have no idea why they chose to impose this restriction, as setting event listeners on individual objects is an extremely common pattern in retained-mode graphics API's (certainly in Draw2d), and, from a technical standpoint, dojox.gfx allows event listeners to be attached to individual canvas objects, so there shouldn't have been any massive technical barriers to implementing it. In any case, this restriction made Tatami unsuitable for this project out of the box, and so I began investigating alternatives.

I've since been investigating the feasibility of scripting pure SVG using GWT. The first possibility I looked into was using GWT's DOM API to manipulate SVG.

The initial consideration was what kind of document would I use to deliver the SVG content? There roughly three possibilities for displaying SVG on the web today, and they are:
1. Via a pure SVG document
2. XHTML document with inline SVG; or an XHTML document with SVG embedded via the object or iframe tags
3. HTML4 document with embedded SVG via the object or iframe tags

HTML5 documents will also allow SVG inlining (without even needing to use XML namespaces!), but I don't think that there are any browsers that currently support this, so I didn't consider this.

What I found was that options 1 and 2 were not feasible, as GWT threw JavaScript exceptions while being loaded in these documents, so that left only option 3.

Option 3 proved to be problematic as well. In principal, what should have occurred was to have the object tag reference an SVG document in its data attribute, and then set an onload event listener on the object tag. Once the object tag has finished loading, then it would be possible to script its DOM via the object tag's contentDocument property. Setting a load listener on a document before scripting its DOM is a very common pattern in web front-end programming, and so I assumed that this would be straightforward to implement with GWT.

Not so. GWT, unfortunately, doesn't support setting event listeners on DOM nodes! I couldn't believe this, because it is such a basic, fundamental feature of HTML DOM, but it's true. I think the motivation for this is that GWT would prefer that you use its built-in widgets rather than low-level DOM. In any case, the effect of this is that it is not possible to listen for an onload event on a document simply using GWT's implemnetation of DOM, so I couldn't script the SVG DOM inside the object tag out of the box with GWT.

I found other problems with GWT's DOM implementation as well. To begin, it does not implement the standard Java interfaces published by the W3C (distributed by the Apache XML Commons). This is problematic because SVG has its own DOM, and while it is not necessary to use it (you can script everything in terms of the standard XML DOM), it would be beneficial to use the SVG DOM in development. Because of the way GWT's DOM has been implemented, it cannot be easily extended to make use of the standard W3C interfaces for SVG.

With these two shortcomings in mind, it seemed that the solution was to actually create a full DOM implementation for GWT in a way that used the standard W3C interfaces. The gwt-dom project started to do this back in 2007, but stopped development after GWT 1.5 included a DOM implementation. On the project page, they say that the project has been made "completely obsolete" by GWT 1.5, but I disagree, as there is still a need for a standards-compliant DOM implementation in GWT, at the very least in order to fulfill the needs of this project. Still, it makes sense to reuse as much of GWT's DOM implementation as possible: it's less work for me to implement and maintain.

To achieve this, my solution has been to use the Adapter Pattern as follows: create DOM implementation classes that extend the standard w3c.dom.* interfaces; these DOMImpl classes compose a type <T extends com.google.gwt.core.client.JavaScriptObject> object, and the DOMImpl classes delegate to this object whenever possible; where not possible, they use JSNI. In this manner, it is mostly possible to delegate to GWT DOM, while exposing a standards-compliant API to DOM that uses w3c interfaces, and I don't have to hack on the GWT core. The gwt-dom project actually has provided a good foundation for this work, as it uses a similar pattern to achieve. One improvement that I have made to gwt-dom is to use Java 5 type annotations so that, rather than simply having each DOM implementation class compose a JavaScriptObject, the wrapped object is a and thus may be specified as far as is practical (for example to a com.google.gwt.core.client.Element), and thus we can have fairly deep integration with GWT. But, overall, I have been able to reuse most of the code in gwt-dom.

There have been some problems so far with this approach so far, but I think this is mostly me tripping over the me tripping over Java's type system. I often need to convert between arbitrary objects that implement DOM interfaces, and GWT DOM objects, and this can be a bit tricky. I have a solution, but it's an ugly one, and I'm hoping to find a better way. I'll post more about this later.

So, my status is as follows: I have HTML DOM scripting working, and I'm now hooking up events. After that, it should be possible to test scripting of SVG content, and I will hopefully be able to start programming against it with respect to Draw2d very soon.

I'm not to sure where this work is going to live when I'm done... upstream in the now-defunct gwt-dom project? I may try to contact the author and see what he thinks.

Thursday, July 9, 2009

Initial Exploration of Draw2d on GWT/SVG

It's been some time since I updated this blog. The short story is, I made some progress with Java2Script, and produced a small prototype of SWT GC on HTML Canvas, which you can see here.

Unfortunately, when trying to compile the next level of the stack, Draw2d, I ran into low-level compiler bugs. I'm continuing to work with the Java2Script developers on these issues, but I don't really feel like I'm in a position to fix or work around bugs in the Java2Script compiler, so my mentor and I have been discussing alternative strategies.

One such alternative is to start a level higher up the SWT/Draw2d/GEF stack, at the Draw2d layer, and attempt to implement the Draw2d API in terms of SVG or dojox.gfx, and use GWT to compile it. This is very interesting to me for a number of different reasons, so I've been drilling down into it. Here is what I have initially determined about the feasibility of this project:

The main problem with this strategy is that the architecture of Draw2d encourages the use of an immediate-mode graphics API, exposed by the org.eclipse.draw2d.Graphics class, which is just a thin wrapper over GC's immediate-mode API.

The way Draw2d encourages the use of this API is by way of subclassing the Figure class. Figure subclasses implement, among other things, the paint or paintFigure methods, which get passed a Graphics instance, and use that instance for drawing. I think the whole process is that LightweightSystem sets up UpdateManager, which knows when to call the Figure's paint method.

This is a problem, because if Draw2d is to be implemented in terms of SVG (or some other browser-based, retained-mode graphics API, e.g. VML), it can't be implemented in terms of an immediate-mode API.

In my opinion, this is a limitation in Draw2d's architecture with regard to our intentions, and I should note that it could have been easily avoided by making Figure protected. This would have forced everything outside of Draw2d to only use the API exposed by Draw2d. Now, however, there's external code that depends on being able to subclass Figure.

Less code than you might think, though. Here are all of the classes in GEF and GEF examples that extend Figure:


org.eclipse.gef.editpolicies - src - org.eclipse.gef
SnapFeedbackPolicy
FadeIn
org.eclipse.gef.examples.flow.figures - src - org.eclipse.gef.examples.flow
SubgraphFigure
org.eclipse.gef.examples.flow.parts - src - org.eclipse.gef.examples.flow
ActivityDiagramPart
org.eclipse.gef.examples.logicdesigner.figures - src - org.eclipse.gef.examples.logic
BentCornerFigure
NodeFigure
org.eclipse.gef.handles - src - org.eclipse.gef
AbstractHandle
org.eclipse.gef.internal.ui.palette.editparts - src - org.eclipse.gef
DetailedLabelFigure
DrawerFigure
PaletteStackEditPart
PinnablePaletteStackFigure
SeparatorEditPart
SeparatorFigure
ToolbarEditPart
org.eclipse.gef.internal.ui.rulers - src - org.eclipse.gef
GuideEditPart
GuideLineFigure
GuideFigure
RulerFigure
org.eclipse.gef.tools - src - org.eclipse.gef
MarqueeSelectionTool
MarqueeRectangleFigure


So, not that many, and nothing from any of the GEF examples. So implementing Draw2D in terms of SVG may not be a perfect fit, but it might still be OK. Basically, the solution would be to limit usage of the Draw2d API only to those Figures that are declared in Draw2d (e.g. org.eclipse.draw2d.Triangle), and to those that are declared in GEF. Here's how we would then proceed:

Each class that implements Figure would keep a private member which is basically an SVG handle, which maps it into SVG. Or, if we don't want a direct dependency on SVG, we can make it even more abstract and just create an INativeGraphicsAdapter interface, then implement classes that basically just a wrap around a handle to the native JS object, exposed via JSNI. Unfortunately, dependency injection is not an option here because Draw2d's figure API doesn't support it and we can't change it. Messing with the class hierarchy (specializing for a particular implementation of this interface), is also not an option. So it seems as though we'll have a strong dependency on some implementation class. I can't see a way around this right now, unfortunately... But maybe the solution is in GWT's deferred binding technique. I'll research this more and see. For the moment, I'll continue to think in terms of having a direct reference to a wrapped native SVG DOM node handle, because it's easier to think about.

The way it would then work is, for each Figure concrete subclass, either in the constructor, or in some init() method, an SVG DOM node gets created, but does not get added to the Document. The IFigure.add() method would add the node in DOM. IFigure.dispose would remove it. All operations in the IFigure API would then get mapped onto whatever native operations on the SVG DOM node are required.

Also note that even though SVG does not natively include a concept of asynchronous updates (where you make a number of updates to a Figure, and it gets applied later on, asynchronously), it would still be possible to make use of this pattern by taking advantage of the fact that we have an extra API wrapping the native SVG. The way this would work is we implement the Command pattern, such that for most operations on IFigure, we create a command and save it in a private queue on each Figure object, and then wait until UpdateManager calls paint to flush all of the operations in the queue.

And that's it.

We will also have some SWT requirements to satisfy, but I expect these to be very minimal, and now that I have a deeper understanding of SWT, I feel I should be able to spec these out fairy quickly and easily.