Hi!
I've been during last days struggling my mind trying to understand what's
the reason that makes the combination of stretch layer with rotate layer
fail in Cairo mode.

After give a try to an idea of a workaround I've understood that the
problem is bigger. The render Cairo system that I've applied to Synfig is
completely wrong. Please let me explain.

In Synfig, as you already know, there are two kind of layers:
Primitives: doesn't care on the context content to produce its result.
Non Primitives (filters): needs to read the context content to produce the
result.

In Synfig, the scale and translate layers are not really filters. They are
transformations. They only modify the render description of the context
applying the inverse of the transformation. I.e. if we need to translate
the context an amount of V (vector) we just modify the viewport (that is
the render description) adding an amount of -V, so the result is that we
are obtaining a translation to the context.
Similar happens to the zoom layer (say amount Z>1). It applies the inverse
of the zoom (1/Z<1) to the render description making it smaller and so, we
zoom in the context when we display the context in the surface that has not
modified its dimensions.

Also, similar happens to the Stretch layer. The Render description is
inverse stretched and then the context is rendered in a inverse stretched
viewport and so, when displayed on the unmodified surface it effectively
looks stretched.

So those three layers doesn't read the context to produce the effect. They
modify the render description to make the context render in a inverse
distorted viewport and so, the result is distorted.

But that doesn't happen with the rotate layer. The render description,
doesn't hold a rotation parameter for the viewport. So, then, the rotate
layer needs to read the pixels of the context to produce the result.

A note: zoom layer is exactly the same than stretch layer but it has the
amount of zoom is interpreted as scale=exp(zoom) so the scale result is
always positive and greater than zero.

On contrary, in Cairo, the scale, translation and rotation are handled as
transformation operations to the stuff to draw.

In Cairo if you want to rotate something around a point OS and after that
you want to rotate it around a point OR, you need to do this:

push translate OS
push scale
push translate -OS
push translate OR
push rotate
push translate -OR
push geometry A
draw
push geometry B
draw

And so the effect is that the geometry A is drawn, then the geometry B and
then the operations are applied in the reverse order (first translate -OR,
then rotate, then translate OR, then translate -OS, then scale and  then
translate OS), giving the desired result.

if we use the current synfig render model for stretch and rotate applying
the Cairo model we have problems with the rotate layer.

I designed the render system with Cairo in the same way than the synfig
model: passing a surface. This implies that the surface is passed between
render calls. Since the surface (I think) doesn't hold the transformations
that are stored in Cairo Context we cannot stack the operations properly
like I explained before, since the Cairo context for the Cairo surface is
destroyed each time. So when a render call is passed from one surface to
other, the cairo transformation stack is lost. (ouch! :-( )

So form this point I think there are two options:
1) Add the rotation parameter to the render description and modify the way
that synfig and cairo renders its stuff (taking account the passed rotation)
or
2) Leave Synfig as it is, and modify Cairo render to pass the cairo context
between calls to properly render the stuff.

The first one would benefit both render systems and that implies more risk
(I can break the synfig render). The second one would benefit only to Cairo
and would probably make the render faster, since there is not need to
convert the drawing commands into pixels and use them as source for the
next operation.

In any case any solution is long :-(

I'm ashamed by this big blunder, but well. That's life =)

Opinions?
-- 
Carlos
http://synfig.org
------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
Synfig-devl mailing list
Synfig-devl@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/synfig-devl

Reply via email to