[cairo] Getting pattern extents.
Donn
donn.ingle at gmail.com
Tue Dec 16 04:51:46 PST 2014
Nicola,
I have produced some code (in vala) using your suggestion. The attached
image shows what's happening.
The larger white rect with the red/green dot and black outline is the
first pattern drawn. At that point I have the data I need to draw the
bbox outline.
The smaller rect, rotated and down, is the second use of the pattern
(the 'stamp' I call it.)
The purple thing to the left it supposed to be the bbox outline around
the second stamp. I used the invert and multiply you spoke of.
If you have any spare time, please help me hack this into some
predictable shape. I want to have a general way to do this, no matter
how deeply nested matrices get.
I really need to get bounding boxes in device *and* user space without
all this pain! I need* them for clipping and for hit-testing.
[* Need is a strong word, this is just a hobby for me! I'm trying to
write a canvas vector drawing app of some kind.]
(If vala is a problem, I can convert it to c and try again.)
Thanks,
/d
I attach the image and here's the code:
-----------------
//HOWTO COMPILE:
// valac --pkg cairo xxx.vala -o test
using Cairo;
double cex1;double cey1;double cex2;double cey2; //clip extents
const double pi2 = 2 * Math.PI;
void scrot( Context cr, double sz, double degs, double x, double y ) {
cr.scale( sz, sz );
cr.rotate( (Math.PI/180.0) * degs );
cr.translate( x, y );
}
void main(string[] args) {
double w; double h;
//Make a demo surface.
Cairo.ImageSurface surface = new Cairo.ImageSurface
(Cairo.Format.ARGB32, 600,600);
Cairo.Context cr = new Cairo.Context (surface);
//Paint it
cr.set_source_rgb(0.5,0.5,0.5);
cr.paint();
//center the axes - 0,0 in middle
var matrix = Cairo.Matrix (1, 0, 0, 1, 300,300 );
matrix.scale (1, 1);
cr.transform(matrix); //<-Matrix zero.
/* !!!!!!!!!!! MATRIX ONE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
//SCROT1
cr.save();
scrot( cr, 1, 0, 0, 0 );
Matrix otm = cr.get_matrix(); //Record the CTM (Will be the 'old' CTM
in next use.)
//Make a pattern
cr.save();
//Draw it and clip it.
cr.rectangle( -25,-25,50,50 ); //to get a path down.
cr.clip_preserve(); //to start clip
//Following uli_test.vala in extents under rot dir
//Gonna save, set identity, and THEN get the extents...
/*
!
! This works! Amazd. I get an axis-aligned device space rect.
!
*/
cr.save();
cr.identity_matrix();
cr.clip_extents (out cex1, out cey1, out cex2, out cey2);
//these vars are now in ... i think ... device space.
//BECAUSE of the identity call before the extents call.
stdout.printf("clip axis-aligned ds extents:
%G,%G,%G,%G\n",cex1,cey1,cex2,cey2);
cr.restore();
//Draw again but to a 'group'
cr.push_group();
cr.set_source_rgb(1,1,1);
cr.fill();
Pattern pat = cr.pop_group(); //grab a cache of that drawing.
cr.restore(); //ends that clip. Also end identity voodoo.
//Draw it. Should I clip?
cr.set_source( pat );
cr.paint();
//okay - let's try to visualize those numbers:
cr.save();
w = cex2 - cex1; h = cey2 - cey1;
cr.identity_matrix(); //Goes into device space.
//i.e. My USER SPACE COORDS are now the same
//as DEVICE SPACE. Go figure.
//ALSO the rotation is gone - the rect is axis aligned.
//Some dots to mark the two points
cr.set_source_rgb(1,0,0);
cr.arc(cex1,cey1,4,0,pi2);
cr.fill();
cr.set_source_rgb(0,1,0);
cr.arc(cex2,cey2,4,0,pi2);
cr.fill();
//The actual bbox rectangle.
cr.rectangle( cex1, cey1, w, h );
cr.set_source_rgb(0,0,0);
cr.stroke();
cr.restore();
/* !!!!!!!!!!! MATRIX TWO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
//Now ... Move the CTM and draw again.
//Can we locate a bbox over this new pattern stamp?
//SCROT2
cr.save();
scrot( cr, 0.5, 67, 100, -50 );
Matrix ctm = cr.get_matrix(); //This matrix
//Draw it again - stamp it.
cr.set_source( pat );
cr.paint();
//Nicola's idea: Pure black magic this... :O
otm.invert();
ctm.multiply(ctm,otm); //ctm is now changed. ctm = ctm * otm
ctm.transform_point( ref cex1, ref cey1 );
ctm.transform_point( ref cex2, ref cey2 );
//The numbers look like they're in USER SPACE.
stdout.printf("After transforming the point:
%G,%G,%G,%G\n",cex1,cey1,cex2,cey2);
//Try drawing something with these numbers:
cr.set_source_rgb(1,0,1);
cr.rectangle( cex1, cey1, cex2-cex1, cey2-cey1);
cr.stroke();
//dots for the two points.
cr.set_source_rgb(1,0,0);
cr.arc(cex1,cey1,4,0,pi2);
cr.arc(cex2,cey2,4,0,pi2);
cr.fill();
//END SCROT2
cr.restore();
//END SCROT1
cr.restore();
surface.write_to_png ("img.png");
}
------------------
/d
-------------- next part --------------
A non-text attachment was scrubbed...
Name: img.png
Type: image/png
Size: 3984 bytes
Desc: not available
URL: <http://lists.cairographics.org/archives/cairo/attachments/20141216/5677203d/attachment.png>
More information about the cairo
mailing list