r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[SVG Renderer] SVG rendering in Draw AGG

shadwolf
1-Feb-2006
[134x2]
hum new rebol/view have save/png hability woooooooooooopy so there 
is nothing that prevent us to make a  graph /AGG/SVG/PNG  dialect 
 ^^
if some one is interressed to make it and need informations i'm ready 
to help  ^^
Anton
1-Feb-2006
[136]
View 1.2.1 has save/png, it's not very new...
shadwolf
1-Feb-2006
[137x8]
Anton i discover it recently  ^^
so for me it's new lol but more serriously until AGG was not available 
i think the use of save/png to-image was really not meaning
on a project like an svg graph system save.png take really all it's 
sens imagine a way to make easyly graphs with your rebol GCI to display 
graph stats in your web pages for example
as svg or as png in a simple and easy way
you have that in php and in ruby or php for example why not rebol 
starting from the point that rebol dialectal ability is incredible 
it's a pitty to not take advantage of it  and show ppl hat rebol 
can apport on this particular application and this gives a good way 
to compare rebol to the other scripting language
some thing like
graph [ line "apple" red  5 12  12 8  line "banana" green  1 2 3 
4 6 ]
would be fun i think
Thør
4-Apr-2006
[145]
.
Pekr
20-Jun-2006
[146]
would following news help us to get AGG - SVG compatible gradients? 
It regards AGG 2.4, new branch of AGG, and I am sure we will get 
it ported to REBOL too ...


New utility class template is added, gradient_lut. It allows you 
to easily create a color LUT for gradients from a set of color stops 
as they are defined in SVG, section Gradients and Patterns.
Normand
1-Jul-2006
[147]
If any person is interested in developping graphs in Rebol they may 
find the following links of interest: www.combinatorica.com which 
have the source code in mathematica for calculating graphs and depicting 
them.  There is also the C library at www.graphviz.org and the many 
little languages drivers.
shadwolf
10-Nov-2006
[148x2]
sur i  do  ^^
okay  thank you for the  link  in my  idea  my  SVG/REBOL graph render 
should be easy to  use and render basical graphs  using  a psecial 
graph dialect  but  ofcourse it  will be enhanced afterward...
Steeve
9-Oct-2009
[150]
Oh my, SVG, what a pain...
Some strange bugs, i can't figure...

As you can see here http://sites.google.com/site/rebolish/test-1/lizard-grad-err.png

I've got some problems to map correctly the gradients on the shape 
they are supposed to cover.

i can't figure why the coordinates of the gradients in the SVG file 
are wrong.

It's not clear (http://www.w3.org/TR/SVG11/pservers.html#Gradients) 
where the gradients should start....
ICarii
10-Oct-2009
[151]
I've been playing with Shadwolf/etc SVG 06 svg renderer today and 
am at the point where i am working on linking in gradients.  The 
test SVG i am using (because it seems to be a good mix) is http://en.wikipedia.org/wiki/File:SVG.svg
Steeve
10-Oct-2009
[152x3]
Icarii, your svg file is too much complicated for me.

It's using both gradientUnits="objectBoundingBox" and gradientUnits="userSpaceOnUse" 
 to render the gradients.

userSpaceOnUse

 use real coordinates for the vectors used by gradients (what i do 
 currently).
objectBoundingBox

  use % vectors which have to be converted into real unit,  depending 
  of the real size of the object (after rendering) where the gradient 
  is applied (what the fuck  !!! it's magic).


I have enough pain to construct correct gradients in real units for 
the moment.Your svg file is too much complicated.
Currently my problem is with the linear gradients when a matrix operation 
is applied on them.


The linear gradient use a vector v = (x1, y1) - (x2, y2) to indicate 
his direction and length.


grad-pen is defined like this:  [grad-pen linear normal xy 0 len 
angle [... stop colors]]

And i calculate his values with:

- xy = (x1,y1)
- len =  length of the vector v 
- the angle of the vector v


When a matrix is associated with the gradient, i multiply the coordinates 
of the vector v by the matrix before calculating the other values.
It's working well when the gradient is vertical or horizontal.

But when the gradient is inclined , the matrix multiplication give 
a wrong vector and i don't know why.
To be precise, the resulting vector seems to have the correct position 
and length, but a wrong angle.
ICarii
10-Oct-2009
[155]
what sort of output are you getting for the angle in the grad-pen 
call?
Steeve
10-Oct-2009
[156]
Well, assuming you got x1,y1,x2,y2 from the Lineargradient

I calculate the angle like that:
arctangent (y2 - y1) / (x2 - x1)

As i said previously, the angle is correct when there is no matrix 
transformation on the gradient.
I compare the rendering with what i see in Inskape.
Steeve
11-Oct-2009
[157x5]
the svg i test currently (public domain) http://sites.google.com/site/rebolish/test-1/lizard.svg
And what i got with rebol: http://sites.google.com/site/rebolish/test-1/lizard-rebol.png
the gradients still have the same problem
when matrix transformations are applied, some are wrong, but hey 
! Quite a good result already !
Well, i think i got it for the linear gradients...
ICarii
11-Oct-2009
[162]
btw the bounding box call in the second sizing mode can be gotten 
from the size of the canvas you are drawing to.
Pekr
12-Oct-2009
[163]
Steeve - your work is quite impressive! Just don't become demotivated 
by possible lack of responses :-) If you find some bugs, or you come 
up with some ideas of how to make View more SVG friendly, write your 
notes down, we can discuss it with Cyphre. I think that we are still 
in rather initial phase, so we can e.g. change the way of how e.g. 
gradient-fills work (I do remember someone reported that you can't 
translate gradient definitions between /draw and SVG)
Steeve
12-Oct-2009
[164x3]
This matrix must not be applied on the gradient's vector as-is, but 
on something else.
And i found what, at least...


The documentation of SVG is lacking of a good explanation about this 
curious matrix transformation.
All we can read is that curious sentence:


When the object's bounding box is not square, 
the stripes that are 
conceptually perpendicular to the gradient vector within object bounding 
box space 
will render non-perpendicular relative to the gradient 
vector in user space 
due to application of the non-uniform scaling 
transformation 
from bounding box space to user space

What does that mean ?????


It means that the SVG gradient must be rendered without using the 
matrix transformation.

And THEN the transformation matrix must be applied on the resulting 
strips.

You see the problem ?

The matrix must not be apllied on the gradient's vector, but on the 
resulting strips produced by the use 
of the initial gradient's vector.


What foolish morons have designed such a complicated way of constructing 
gradients.

Can't they just give a matrix that can be applied on gradient's vector 
as-is, no they can't, it's to simple.
Morons, I said !!!


Because of that i had to make more transformations to obtain the 
REAL vector.
step by step I do something like that:


1/ Take the initial gradient vector V and apply the matrix on it, 
it gives a vector V1

2/ RE-take the initial vector V, rotate it of 90 degrees, apply the 
matrix on it, and rotate back the resulting vector
. It gives the vector V2

3/ Project the vector V1 on the line V2 (orthogonal projection). 
It gives a third vector V3.
4/ That's all, the REAL vector to use for the gradient is V3.


It take me a while to figure that, by analysing the Inkscape rendering. 
Morons i said !!!
I show you that part of my code...

		switch type [
			linear [
				unless x2 [x2: x1]
				unless y2 [y2: y1]

				if matrix [

     ; ** apply the matrix on the vector rotated of 90°, then rotate it 
     back,  give the vector V1
					set [y1' x1'] mulm y1 negate x1 matrix
					set [y2' x2'] mulm y2 negate x2 matrix
					x1': negate x1'
					x2': negate x2'

     ;** apply the matrix on the initial vector, give the vector V2
					set [x1 y1] mulm x1 y1 matrix
					set [x2 y2] mulm x2 y2 matrix
					;** project the vector V2 on the line V1
					set [x1 y1] project x1' y1' x2' y2' x1 y1
					set [x2 y2] project x1' y1' x2' y2' x2 y2
				]
				angle: atan2 x2 - x1 y2 - y1 
				if units = "objectBoundingBox" [
					x1: box/1/x * x1
					y1: box/1/y * y1
					x2: box/2/x * x2
					y2: box/2/y * y2
				]
				out as-pair x1 y1	;** offset
				out 0				;** start rng
				out square-root add x2 - x1 ** 2 y2 - y1  ** 2	;** stop rng
				out angle			;** angle
			]
...
Well i thought SVG 's radialGradients will be easier. I was wrong.
SVG Proposes another stupid feature (yet another one).
Actually they can specify 2 circles.

One where the gradient is really rendered. And another one used as 
a window which clips the first one.
What the heck is that !!!!

it's why in a SVG's radial gradient, there is 2 different  centers 
 (cx, cy) (fx, fy)  for the 2 separated circles.


When the 2 centers are equals, then there is no prolem to render 
it whit the rebol's radial gradient, easy.
But when they differ, it's impossible.

I can't blame Rebol to not allow that, because it's a really stupid 
useless feature.
Pekr
12-Oct-2009
[167]
Now the question is - should we adapt, or do we create copy of such 
functions, to allow being compatible?
Steeve
12-Oct-2009
[168x8]
I'm angry, i don't see why grad-pen in Rebol should allow such stupid 
feature
in fact, i think i could simulate that behavior.
By 
1/ rendering the radial gradient in the initial circle.

2/ create an image with that circle and clip it with the shape of 
the second one.
3/ Use that image as a pattern for the fill-pen attribut


But it would be a mess of  computing time and of memory, because 
in the draw block we would have images used as pattern instead of 
computed gradients
i think that feature (2 different centers) is not used that much.

In the lizard.svg example i gave, they don't use it, the 2 centers 
are always equal.
By default Inkscape don't use that feature when you design a radial 
vector.
Ok, i finished with Radial gradients (less the impossible feature: 
2 different centers)


SVG use a matrix transformation to convert a circular radial gradient 
into an ellipsoid.

And you know what ? 

We can do the same thing with grad-pen which provides 2 scalling 
factors (grad-scale-x and grad-scale-y)

So in that case it's easier than for linear-gradient.
1/ take the focal point of the Radial gradient (fx, fy)

2/ Create 2 vectors starting from this point: 1 vertical and 1 horizontal, 
using the radius as their length.
3/ apply the matrix transformation on them.

5/ get  the component X of the transformed horizontal vector, and 
the component Y of the transformed vetical vector
6/ grad-scale-x:  x / r
7/ grad-scale-y: y / r

That's all folks
Gezz... i forget the rotation of the ellipsoid...
more work...
Ok, done
Guys, i updated the lizard.svg rendered with Rebol http://sites.google.com/site/rebolish/test-1/lizard-rebol.png

To compare with http://sites.google.com/site/rebolish/test-1/lizard.svg.


I'm glad to announce that i see absolutly no differences inside Google 
chrome.

All the grandients (linear and radial) are perfectly rendered by 
Rebol.
Graham
12-Oct-2009
[176]
Nice ...
ICarii
12-Oct-2009
[177]
great work steeve! :)
Steeve
12-Oct-2009
[178]
Basically, you can load the draw block generated for the lizard here.
it's handed by the variable PANE.
http://sites.google.com/site/rebolish/test-1/lizard.r
Maxim
12-Oct-2009
[179]
GREAT WORK Steeve  :-)
Steeve
12-Oct-2009
[180]
Added a litte animation.
The bumping lizard !!!!
http://sites.google.com/site/rebolish/test-1/lizard.r
Maxim
12-Oct-2009
[181]
the difference in your render and SVG render is mainly the anti-aliasing, 
which is crisper in the svg renderer.... probably has a better algorythm 
setup than the one use by R3... this is probably manageable within 
AGG, but AFAIK there is no control for it within R3.
Steeve
12-Oct-2009
[182]
Not the problem of the antialiasing, I just think i made a false 
translation of the command used in the shapes.

They use a smouthing curve, me not i guess. I have to verify that.
But Rebol can draw smoothing curves too, no problemo.
Maxim
12-Oct-2009
[183]
if you draw the outlines twice, they should be a bit crisper... is 
that what you mean?