The TODO list for cairo is separated into things to improve this website and things to improve the cairo library itself.
Website improvements
Integrate existing reference manual into the wiki proper and enable auto-updating from source code comments.
Fix these broken links (if any):
- others from roadster
Library improvements
This is an attempt to collect all good ideas that have been proposed for inclusion in cairo. None of these items have been scheduled for a particular release, (see roadmap for those).
If you'd like to see an item on this list get into a particular release, let us know that you're planning on working on it, (via the mailing list), and you can move the item to roadmap with your name on it.
Changes that add new API (API changes/removals will not be considered)
Add cairo object constructors to create objects in an invalid state. Currently the user needs to jump through kludgy hoops to get this done.
Add
CAIRO_FILL_RULE_INVERSE_WINDING
andCAIRO_FILL_RULE_INVERSE_EVEN_ODD
or another way to provide that functionality.Add
cairo_arc_to
.see Behdad's proposal with patch or the
arc_to
branch in Behdad's repositorySupport [limited] CSS aliases for all backends in the toy API
Map "sans", "serif" and "monospace" to appropriate names for the platform in order to simplify writing demonstration programs. This has greater merit now that "cairo" means something special to the toy API.
Refactor toy-font face and expose internal implementation
Behdad's outline.
Extend line caps/joins to include "triangular cap/join" and "no join"
As defined by PCL, example on page 213. The triangular cap is constructed by adding a point one half-line width midway beyond the end points, and the join by adding a point one half-line width beyond the midpoint of the vector connecting the two outer edges.
Add support for custom caps
It would be nice if the user had a mechanism to reliably draw custom caps. One approach here would be to provide the coordinates of the butt cap faces so that the user can append seamless caps to the current path. We may also need to provide the coordinates of the faces of every dash as well.
Polling API (
cairo_get_serial
andcairo_changed
)cairo_save
/restore_path()
http://lists.freedesktop.org/archives/cairo/2007-April/010363.html
cairo_save_state
/cairo_restore_state
()http://lists.freedesktop.org/archives/cairo/2006-January/006187.html
cairo_copy_clip()
andcairo_copy_clip_flat()
http://lists.freedesktop.org/archives/cairo/2007-April/010520.html
Add a move-current-point-but-don't-make-a-new-sub-path API, (bulia byak wanted this for an inkscape optimization). See:
http://lists.cairographics.org/archives/cairo/2008-April/013651.html
Obviously it will need a real name first.
Add support for backends implemented in external libraries.
Decode on draw for compressed and palleted/indexed images. This would be useful for Firefox and a reimplementation of GdkPixbuf
Full user backends implemented outside of cairo proper
For reference see similar API in quarz: http://developer.apple.com/documentation/GraphicsImaging/Reference/CGImageSource/Reference/reference.html
Proposal: mime-surface (ickle) A convenience surface for lazily decoding compressed image data. http://lists.freedesktop.org/archives/cairo/2008-November/015785.html
Add a
cairo_in_clip
functionExport
cairo_surface_snapshot
Export meta surfaces
Examples for possible uses: a combined surface https://bugs.freedesktop.org/attachment.cgi?id=5764, multipage surface (like psnup, page selection, reverse ordering) 0, 1, 2, 3 and 4.
Add projective transform, which is already in pixman. Currently only affine matrix transformations are supported.
Further comparison of cairo with other vector graphics languages, and in particular features that cairo lacks, can be found in missing.
Performance improvements
- Special-case extreme scaling of dashed lines i.e. when dashes are sub-tolerance
To quote Carl, "We can take the maximum single length from the
dash sequence, (either drawn or not), and compute its maximum size in device
space. (We should have code for that part in cairo_pen.c
).
Then if that length is less than the tolerance, multiplying the current alpha by the percentage of the dash sequence that's lit, then stroking a solid line should be sufficient."
An incomplete patch can be found here: https://bugs.freedesktop.org/attachment.cgi?id=2277
A remaining task is "One approach that would work is a sliding integral over the pattern with a 1-pixel-wide window, checking for a constant value at every position, (after rounding based on the maximum 8-bit alpha depth)."
Again profiling, and a perf-case showing the improvements are also necessary.
Improve software polygon compositing by doing it in a single scanline pass rather than tessellating, rasterizing, then compositing the entire polygon.
- Partially completed by Joonas Pihlaja by implementing spans for fills, stroking however depends upon stroke-to-path and so currently fallbacks to using trapezoids.
SVG font embedding
Inline fixed-point operations. (Needs profiling)
Can we speed up rounded-corners on rectangles? The vast majority of the pixels lie within square sections of the rectangle, so the performance should nearly be on a par with the simple square-cornered case. Is it? Can we improve?
Use MIT-SHM when available for X11.
- Example patch as part of the mime-surface enhancement.
- However using SHM is not a clear-cut performance enhancement, as there are notable regression when using SHM image pattern with text for example.
- An alternate patch which creates a whole new surface and does not address using SHM for fallbacks is available with further commentary.
Add an extend mode that does the right thing and make it default. EXTEND_NONE is rarely the desired behaviour. The desired extend mode should be like EXTEND_PAD and then clip. To have this mode work properly you need to know the coverage that the source surface has over the destination surfaces. i.e. the edges need to be antialiased after scaling. Quartz has the behaviour we want here.
A list of pixman projects (a core component for Cairo) is available here.
Other fixes
Fix/define tolerance for PS/PDF/SVG backends
Fix define glyph extents for FreeType. Currently if hinting is enabled, it returns integer extents, which is not necessarily tight to hinted glyph path.
Fix
CAIRO_EXTEND_REFLECT
in pixman and remove the current hack Update: it is fixed, so time to remove the hack! Need to still provide a helper function for backends that require it.Possibly remove pdiff (slows down the test suite with little benefit)
Make font backends separable from their native surfaces
Fix cairo so that a degenerate matrix draws nothing rather than triggering an error state. That is:
cairo_scale (cr, 0, 0);
should not cause an error, (though maybe it shouldn't actually draw nothing for painting an infinite source pattern---compute the average color for a surface-based source pattern perhaps? It may also draw something for a stroke if pen-locking (below) is implemented).The new tessellator has greatly improved performance, robustness, and code readability, but may still suffer from "missed intersections" as described here:
http://cm.bell-labs.com/cm/cs/doc/93/2-27.ps.gz
[Hobby93c] John D. Hobby, Practical Segment Intersection with Finite Precision Output, Computation Geometry Theory and Applications, 13(4), 1999.
We could do multi-pass Bentley-Ottmann or add a tolerance-square pass as described by Hobby in the paper above.
Improve bitmap-to-vector glyph conversion
As per usual, John Hobby has a few words of advice on the subject:
Fix vertical metric and TrueType subsetting:
Text drawn with vertical metrics cannot currently use TrueType subsetting for PDF/PS output as the code doesn't write out the necessary VHEA or VMTX entries to the TrueType font objects. As a result, cairo uses Type3 fonts which generates slightly different outlines. Type1 has the same problem.
Add API to cairo to allow enable/disabling certain subsetters.
https://bugs.freedesktop.org/show_bug.cgi?id=8180#c28
Pen matrix locking. Behdad thinks that Carl has written an excellent summary that unfortunately was not sent to the mailing list. Carl can't remember if such a thing exists (sorry!).
But there are two mailing-list threads that go into the issues in quite a lot of detail:
Adventures in line widths Problems with
cairo_get_line_width
and "new" semanticsCarl says: The history there is that I was working hard to fix in the 1.2 release what I saw as a big semantic bug in cairo 1.0. But this was also too disruptive a change very late in the cycle, and I also feared introducing problems by breaking backward compatibility. So nothing has changed, (not in 1.2, 1.4, nor 1.6).
Today, I'd still like to make it easy to get the "new" behavior. We'll probably need to make it so that the user can explicitly request it somehow, but that old code continues to work as it always did. I'm not sure. But I'm definitely hoping that someone other than me will step up and argue for something, (with code in hand---even if its mostly code I originally wrote). I'd much rather review and "bless" something than try to push for a change here.
Font matrix locking as well.
Explore Render-like component-alpha ARGB masks
Rotated text is not keeping baseline due to glyph cache, that stores only single image of a letter: [1] example, source code
Enable X server-side gradients (cworth)
Fix all remaining XFAIL failures from the test suite.
Update bindings chapter of documentation to reflect new APIs (
get_reference_count
() anduser_data
for all)Implement a faster lookup-table-based rasterizer (cworth)
Internal move to
cairo_object_t
(Chris 'ickle' Wilson)Make cairo-xcb a supported backend (Jamey Sharp)
Add "/Interpolate (true|false)" to PDF image dictionaries. And fix Poppler to respect the Interpolate flag.
Clip mode needs to "upgrade" to
CLIP_MODE_MASK
. See patch here:http://lists.cairographics.org/archives/cairo/2008-March/013373.html
and original mozilla bug here:
Fix leaks found by "make TESTS=self-copy check-valgrind"
Use a solid-pattern in place of 1x1 surfaces: source
Transparency should be optionally flattened to a new path rather than a bitmap.
Currently PS/EPS surface flattens transparency to a bitmap. This can make a resulted file much larger than it could be. A good solution would be to flatten transparency in overlapping regions to new paths that have opaque fill matching the transparency projection.
Make
cairo_surface_show_page()
call XFlush() (and friends).Is this a good idea? What does it mean and what impact will it have? Discuss.
FSAA (full-scene antialiasing)
Can be done on top of cairo, but it would useful to have a reference implementation. In many things this is akin to fallback resolution, and so it would be a useful exercise to do this with an exported meta-surface...
1) Create intermediate target image scaled up by a factor of N in both directions.
2) Disable anti-aliasing.
3) Tolerance? Other scaling issue?
4) Draw scene
5) Down-sample intermediate target surface.
6) Return as pattern/surface
Add a
cairo_pattern_copy
function:http://lists.cairographics.org/archives/cairo/2008-October/015316.html
Eliminate objects entirely outside the current clip region
See a use-case in: Message-ID: 4B6DB866.30808@gmail.com
Backend-specific improvements
Win32 backend
- Fix self-copy test
- Fix trap-clip test
- Hardware Acceleration of some sort
- win32 rendering fails for rotated bitmap fonts
- HDC multithread conflict [1]
Xlib backend
- Switch to using XRenderAddTraps rather than XRenderCompositeTrapezoids
OpenGL [new]
Implement a fully hardware accelerated backend. Glitz is only designed to be an implementation of XRender on top of OpenGL, and therefore only provides accelerated composition. The goal of a future OpenGL backend would be to investigate offloading more computation, such as rasterization, to the GPU. There have been a number of experiments along this direction - see drm, opengl, gl and gral. They each have their own limitations...
Instead of adding an OpenGL backend, an alternative would to write a cairo state tracker for gallium.
- PCL [new]
New backend to output Printer Command Language.
- WMF [new]
Cross-platform backend to generate Windows Meta Files.
- QPainter [new]
Mozilla wrote a backend to interface with QT so that they could port their applications to Qtopia.
The implementation is here: mozilla-central updates, an old patch for cairo.
Outstanding issues: * No test suite integration. * Use of C++ badly breaks autotools when linking without it included.
Test-suite improvements
- Single binary
- Fine grained XFAILs (per-target)
- Required version for each test
- Print out used versions of external libraries and converters
- Keep pdf,ps,svg reference targets to be used for comparing target output, bypassing the requirement for external renderers (which are outside of our control). However, we still need them to confirm the result in case a backend changes. Perhaps we need an automated tool to check results and update reference targets?
- Smoke testing, without loss of confidence
- Group tests by high level calls, e.g. clip, paint, stroke, fill
- Move output to a separate directory (apparently 30,000 output files slows tab-completion, and don't try GtkFileChooser on it!)
- Font integration
- Font-backend specific reference images?
Quick mode: disable similar testing, device offset iterations.
From https://bugs.freedesktop.org/show_bug.cgi?id=9465#c2
I prefer finding the font backend using
cairo_font_type_t
. For example usingcairo_get_font_face()
+cairo_font_face_get_type()
. Unfortunately this probably doesn't work. It probably returnsCAIRO_FONT_TYPE_TOY
. We needcairo_get_scaled_font()
API first.We probably should do something more clever now that the involved parameters are increasing. Marking tests as having text is probably one thing we want to do.
Exercise double->fixed, fixed->double
Possible test case:
- Take primitives, draw them at integer - epsilon integer + epsilon test that the result is pixel-the-same.
Review double => integer conversion when calling the backend interfaces, which take integers (should be a case for static analysis).
Wide integer unit tests
An introductory set of fixed-point tests can be found in https://bugs.freedesktop.org/attachment.cgi?id=6504, but that currently requires using private headers from the test-suite. The best idea so far is to have unit tests inline with the code and conditionally compiled in for tests cases built alongside the library main (i.e. -DMAIN).
Use checkered background
Review tests that paint semi-opaque objects over a solid background and replace the background with a checkerboard pattern so that alpha compositing is more thoroughly tested.
Integration improvements
Not strictly in cairo-land, but noted lest we forget.
GdkPixbuf export/import cairo surfaces.
- Add a pre-multiplied ARGB colorspace to avoid conversion issues, and make GdkPixbuf match hardware requirements for improved performance
refactor GdkPixbuf for Gtk 3.0, so it's a thin wrapper around cairo surfaces and make sure it makes use of Cairo performance effectively:
- make GdkEditablePixbuf different from GdkPixbuf (treat editing as a special case)
- ensure loaded-from-file pixbufs store their raw image data for writing to JPEG
- possibly add subclasses for themed pixbufs/icon pixbufs and invent a sane object hierarchy
Student Projects
The following list of ideas was from Cairo's participation in the Google Summer of Code 2008, which saw Joonas Pihlaja undertake a Scan converting rasteriser project.
Each idea below is given a difficulty estimate, (Easy, Medium, or Hard), determined by one of the potential mentors. Please use these ratings to help choose an appropriate project. If a project description uses terms you've never heard of and is also rated Hard, then you can know that that's a project that will provide plenty of learning experiences for you. If a project is rated as Easy, then maybe it won't keep your interest and give you the intellectual challenge you're looking for.
[Medium] Implement a faster lookup-table-based rasterizer
Cairo's software rasterization currently does a complete walk of a regular 15x17 sampling grid for ever pixel in order to compute coverage. This is quite slow. It would be great to have something much faster.
With the recent change from 16 bits of sub-pixel precision to only 8 bits, (and perhaps even throwing some of those away), there's perhaps something easy to do. One approach would be to generate a lookup table based on all possible input and output positions of a trapezoid edge to a pixel. Then rasterization can become nothing more than 1 to 4 table lookups for each pixel.
[Hard] A significant improvement to pixman compositing code
We know that we want something that is more dynamic than the current approach of hand-writing optimized MMX/SSE2 functions for special cases. We have a proof-of-concept of dynamic code-generation for pixman in the jitblit library, but nothing that's in a form suitable to ship, (due to unfinished parts of the compilation framework that jitblit uses).
One possible approach would be to instead base a new framework on LLVM Søren also has some ideas about doing something somewhat dynamic, but much less aggressive than the kind of approach taken with jitblit.
[Medium] Merge XLib and XCB backend similarly to what was done recently to PDF and PS
Currently there are separate XLib and XCB cairo surface backends. The problem is, the XCB backend is not maintained and does not get the same treatment (bug fixes, improvements, ...) that the XLib backend does. The two also duplicate a lot of code. The idea is to merge the duplicate code, possibly using a similar approach used to make the Postscript and PDF backends share code, namely, cairo-pdf-operators.c.
[Medium] Implement
cairo_stroke_to_path()
This API function provides a new path that the outline that would be formed by computing a stroke of the current path. The current stroking algorithm does compute this path, but the path has some undesired self-intersecting regions in it. These self-intersections need to be detected and eliminated. The intersection-finding code at the core of cairo's tessellation implementation should provide all the primitive operations necessary for this.
[Hard] Improve software polygon compositing by doing it in a single scanline pass rather than tessellating, rasterizing, then compositing the entire polygon.
[Medium] Fix cairo so that a degenerate matrix draws nothing rather than triggering an error state. That is:
cairo_scale (cr, 0, 0);
should not cause an error, (though maybe it shouldn't actually draw nothing for painting an infinite source pattern---compute the average color for a surface-based source pattern perhaps?).[Hard] Add appropriate color-management support to cairo.
Cairo needs the ability to allow for color management. By this project it will become possible to work in different color spaces, convert automatically to blend different content and tag graphics objects to tell backends about the color spaces involved. The color space information will follow the ICC standard.
In this project you will learn about the constraints at different OS'es and handle API abstraction. During the programming work you will design and implement the corresponding means covering frontside API's and backend specific code due to file formats and other specific requirements. A small application, showing the new capabilities, will help in spotting problems and can later be used for demonstrations. A unit test and documentation is required for maintainablility and further easy deployment.
Some relevant threads from various mailing lists:
- Color, Cairo and Cups
- PDF, CMYK and cairo
- Creating CMYK and spot colors using Postscript backend
- Tessellating complex figures with Render contains a subthread on color spaces.
Ideally this should also incorporate HDR as discussed in the next suggestion.
[Medium] Add HDR image surface type to cairo/pixman (
CAIRO_FORMAT_ARGB64
).The new image format will implement the scRGB colorspace. This involves either extending the pixman library to support the new format, or write code for Porter-Duff compositing on the new format and make cairo use them for ARGB64.
Conversions between the 16-bit floats used by colour spaces such as scRGB and 32-bit floats should use the algorithms explained in Jeroen van der Zijp’s Fast Half Float Conversions.
[Easy] Add a performance/conformance suite for the vector backends.
One goal would be to aim to make the output file size competitive to other generators (e.g. gs). Conformance could be checked by running the test output through various validators: SVG validator.
[Hard] Add support for PDF/PostScript Type 6 (Coons patch mesh) and/or Type 7 (Tensor-Product patch mesh) shading functions to the image backend
The Type 6 shading is a special case of the Type 7 shading so only implementing Type 7 may be all that is required.
One possible solution would be to create a triangle mesh (similar to Type 4 shadings) from the Type 7 patch mesh and shade the triangles using Gouraud shading.
The Poppler source may be used to get an idea how Poppler renders these gradients . However the approach Poppler uses of recursively breaking each patch into smaller patches then filling the tiny patches with a solid color is not appropriate for cairo due to the visible seams between patches due to antialising.
The algorithm for Gouraud shading is in many books on computer graphics.
Useful references:
[Hard ?] Implement path operations like combine/intersect/overlay
A robust "intersection finder" is at the heart of all of this (that's the hardest part). It would start with robust primitives for polygons, intersecting two paths would do a polygonal approximation of the curves, do the intersection, and return a path that has no curves in it. And then could be potentially extended to have curves in the output. An example of direct 'visible impact' could be an ability to extend cairo's clipping functions with something like
cairo_clip_exclude(cr)
andcairo_clip_invert(cr)
.