[cairo] 64 bit fixed point in Cairo?
nick.allen at onlinehome.de
Thu Apr 14 03:14:59 PDT 2011
Thank you for your reply.
I've been debugging cairo a bit and noticed that cairo_rectangle calls
cairo_rel_line_to and that this method needs to convert the double to a
cairo_fixed_t. At this point the 24 bits allocated for the integer part
overflows and this is where all the problems begin.
I can't see anyway to change our application to handle this except to do
the clipping in our application instead of relying on cairo to do it.
When we are zoomed in we will have rectangles and rectangle strokes that
are much larger than 16,000,000 pixels wide as well as other filled and
stroked primitives. The only way we can send this to cairo is as large
numbers - no matter where we translate to we can't avoid the fact that
the primitive shape is extremely wide. We would need to implement our
own clipping for every primitive which would be as difficult as writing
a new graphics library - definitely not something we want to do!
The only solution for us that I can see is if cairo could use 64 bit
fixed point instead of 32 bit. I'm going to take a look at hacking this
in cairo and seeing how far I get. I take it no one else has yet
attempted this? If this turns out to be a lot of work we will have to
consider using another graphics library.
Bill Spitzak wrote:
> Ideally Cairo should transform floating point to the final
> coordinates, then correctly clip off graphics that are outside the
> output surface (which is assumed to be smaller than 2^24). Then it can
> do all the rest of it's work in 24.8 numbers, perhaps pushing all this
> decisions into the back ends.
> It is not doing this now but I think that is the correct solution. It
> means the transformation matrix has to be floating point (though there
> could be flags to indicate what parts are different than the identity,
> and the translation component could be split into a 24.8 addition if
> this will keep the xy offsets in the matrix zero.
> You should be warned that if you zoom way in on a location that is far
> from the origin, you will see serious artifacts due to the low
> resolution of large floating point numbers. You may want to rethink
> your source data into a hierarchy, so that for each "object"
> coordinates are close to zero and the object is parented to a
> translation that moves it to closest floating point value in absolute
> space. This would also allow you to avoid Cairo's bugs by setting it
> only to the difference between the whole-scene translation and the
> local object translation before drawing.
> Nicholas Allen wrote:
>> We have an application that has its own widget framework that uses cairo
>> to render its graphics. We are noticing graphical glitches and mistakes
>> when we pass large coordinates to cairo's functions (values in the range
>> of around 8 million). These large coordinates occur because we have a
>> scroller widget that contains a very large widget that the user can
>> scroll around. The user can zoom in and out of this widget so the widget
>> can easily get to much more than 8 million pixels wide. Ideally we would
>> like to support values upto around 1 << 50 (so 8 million is a extremely
>> low limit for us). When the widget being scrolled is painted we
>> translate by its position inside the scroller and then clip using the
>> widget's bounds and then the widget paints itself.
More information about the cairo