DXCanvas – a canvas implementation for DesktopX
Every major browser has support for it, Yahoo! Widgets has support for it, how come there isn’t something for DesktopX?
Enter DXCanvas, a DesktopX drawing plugin that implements the Canvas spec (plus some DesktopX-specific additions).
How does it work
DXCanvas is a DesktopX drawing plugin, which means it takes over drawing for the object it is associated to.
In the configuration, you can set the initial size for the canvas. By default, the drawing surface size will be 300×150. You can also specify whether you want the surface to be transparent and show the other objects or windows under it, or opaque.
A canvas object is made available to scripting. To be able to draw on the canvas, you need to request a context. This is done by calling getContext(type) on the canvas object. The only supported type right now is "2d".
See the list of functions in the implementation section. Note that some are slightly different from the Canvas specification, or are completely new. This is to adjust to differences in what is possible in a browser and in DesktopX.
Canvas Controller Widget
I’ve made a little widget to make testing easier. It loads a list of scripts from a user-defined folder and allows you to switch between them. It support scripts written in both JScript and VBScript.
It basically associate the script to an object having the DXCanvas plugin as a capability.
Two functions are required for the scripts to work: Object_OnScriptEnter() and Object_OnScriptExit().
The canvas size is reset its default size of 300×150 when switching between scripts, so make sure to set it to the required size if needed by your script.
To add a new script to the list, create a new .js or .vbs file in a folder and select this folder in the widget preferences. A few test scripts are included in the Script folder.
It also support subfolders (only 1 folder deep), so you can organize your scripts in subfolders.
How to help
Download the Canvas Controller widget and start creating scripts!
What to look for
- strange behavior: colors are not right, context is not saved or restored correctly, etc.
- the output from a script is different in Firefox or Safari
- crashes or memory leaks (there are a least a few :P)
What is broken/not working properly
- Drawing still flicker (not as badly as before)
- This is a DEBUG build, so it’s going to be slower than normal
- HTML5 Spec on Canvas
- Canvas Tutorial
- Yahoo! Widgets Canvas Documentation (Look in Core DOM Reference -> Canvas / CanvasRenderingContext2D)
1.0 Build 225:
- Fixed large canvas objects taking a lot of CPU
- Log is always enabled
1.0 Build 217
- Fixed drawing being incomplete in some cases
- Added workaround for pink color drawing transparent. DesktopX always use pink to draw transparent surfaces, even in per-pixel mode. rgb(255, 0, 255) will be changed to rgb(255, 1, 255)
1.0 Build 214
- Added per-object log files
- Added more log info when creating a new context object
1.0 Build 211
- Added support for % in rgb/rgba colors
- Added "transparent" color (equivalent to "rgba(0,0,0,0)")
- Added SVG colors "darkgrey", "darkslategrey", "dimgrey", "grey", "lightgray", "lightslategrey" and "slategrey"
- Zero size canvas is allowed
- Properly share canvas state (context style stack was not properly shared before)
- DrawImage and DrawImageRegion check for negative width and height and adjust the coordinates
- Only match full color strings
- Accept rgb values outside [0;255] and clamp the value properly
- Clamp alpha and use premultiplied color values when painting with alpha (still somewhat wrong)
- Fixed leak and crash with CanvasImageData & CanvasPixelArray
- Fixed crash with invalid parameters in createImageData and getImageData
- Zero-length line gradients should paint nothing
- Radial gradients with the same start and end circle should paint nothing
- Image data now accepts negative width and height (you get the untransformed data for the resulting rectangle)
- arc() with zero radius draws a line to the start point.
- arcTo() has no effect if the context has no subpaths or if P0 = P1
- arcTo() draws a straight line to P1 if P1 = P2 or if radius = 0
- bezierCurveTo() has no effect if the context has no subpaths
- lineTo() has no effect if the context has no subpaths
- quadraticCurveTo() has no effect if the context has no subpaths
- Updated cairo, pixman and pango libraries
1.0 Build 201
- Added hsl/hsla color parsing
- Added some logging (DXCanvas.log in object directory)
- Fixed text stroking always drawing at position (0,0)
- Fixed text baseline being off by the text height
1.0 Build 191
- Added redraw calls buffering (less flickering)
- Added debugMode attribute to canvas. In debug mode, passing invalid parameters will result in an error being raised instead of the invalid value being silently ignored.
- No longer returns errors when passing invalid parameters to a lot of functions (as specified in Canvas specification)
- CanvasPixelArray.XXX6(index, value) now takes an int instead of a char and will clamp that value to [0;255]
1.0 Build 180
- Implemented toImage
- Implemented createImageData, getImageData and putImageData
- Added canvas support to createPattern, drawImage and drawImageRegion
- Fixed createPattern, drawImage and drawImageRegion not working in VBScript
- Fixed createPattern, drawImage and drawImageRegion not making a copy of the source image or canvas
- Fixed drawImageRegion using wrong default values for dw and dh
- Fixed drawImageRegion not creating a new path, resulting in image "corruption"
1.0 Build 168
- Implemented font attribute setter/getter
- Implemented fillText, strokeText and measureText (using Pango)
- Implemented arcTo (using patch from Behdad Esfahbod)
- Fixed image loading (SD_LOAD_IMAGE seems to be corrupting some images…)
1.0 Build 159
- Implemented textAlign and textBaseline attributes setters/getters (not used yet)
- Implemented createPattern, loadImage, drawImage and drawImageRegion
- Update to cairo 1.7.4 (better support for text)
- Statically linked to cairo lib (no need for cairo.dll anymore)
1.0 Build 149
- First test version
You can download a test version here. It only includes the Canvas Controller widget for now. Please do not use the DXCanvas plugin in your own objects and widgets yet. This version of the plugin will expire on the 10/01/2008.
Under the hood, it’s using Cairo, a 2D vector graphics library that also powers the Mozilla and Yahoo Widgets implementations. Right now, the Cairo library is dynamically loaded at runtime, but I hope to have it statically linked into the plugin for the final version.
Here is a list classes with their attributes and functions and the state of their implementation
|debugMode||YES||Invalid input will raise an error instead of being ignored.|
|toImage(path)||YES||Saves to a PNG file (replaces toDataURL)|
|shadowOffsetX||YES||Shadows are not implemented yet.|
|shadowOffsetY||YES||Shadows are not implemented yet.|
|shadowBlur||YES||Shadows are not implemented yet.|
|shadowColor||YES||Shadows are not implemented yet.|
|textBaseLine||YES||Hanging and ideographic baselines are treated as alphabetic.|
|transform(m11, m12, m21, m22, dx, dy)||YES|
|setTransform(m11, m12, m21, m22, dx, dy)||YES|
|createLinearGradient(x0, y0, x1, y1)||YES|
|createRadialGradient(x0, y0, r0, x1, y1, r1)||YES|
|clearRect(x, y, w, h)||YES|
|fillRect(x, y, w, h)||YES|
|strokeRect(x, y, w, h)||YES|
|quadraticCurveTo(cpx, cpy, x, y)||YES|
|bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)||YES|
|arcTo(x1, y1, x2, y2, radius)||YES|
|rect(x, y, width, height)||YES|
|arc(x, y, radius, startAngle, endAngle, anticlockwise)||YES|
|fillText(text, x, y)||YES|
|strokeText(text, x, y)||YES|
|drawImage(input, dx, dy, dw, dh)||YES|
|drawImageRegion(input, sx, sy, sw, sh, dx, dy, dz, dh)||YES|
|getImageData(sx, sy, sw, sh)||YES||image data uses the BGRA format|
|putImageData(imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)||YES|