Re: Text stuffing with Cairo/pycairo?

[email protected] Tue, 30 Apr 2019 17:48:02 +0000 (UTC)
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
--===============1811114430==
Content-Type: multipart/alternative; 
	boundary="----=_Part_2814875_1393427384.1556646482267"

------=_Part_2814875_1393427384.1556646482267
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

=20
Hi Warren,

Have you made some progress with this?

Well, you might need some font metrics and get the transforms in order to b=
e able to do this. The following is in C but it might be helpful. Probably =
need to change a few things around but it is a start.

Eric=20

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=20
//gcc -Wall cairo_text_size.c -o cairo_text_size `pkg-config --cflags --lib=
s cairo` -lm

#include<cairo.h>
#include<cairo-pdf.h>
#include<stdio.h>
#include<math.h>

static void text_in_box(cairo_t *cr, double center_box_x, double center_box=
_y, double box_width, double box_height, double rotate, char *string);

int main()
=C2=A0 {
=C2=A0=C2=A0=C2=A0 double width=3D600.0;
=C2=A0=C2=A0=C2=A0 double height=3D600.0;
=C2=A0=C2=A0=C2=A0 char *string1=3D"Center String";
=C2=A0=C2=A0=C2=A0 char *string2=3D"Translate Stringssssss!";
=C2=A0=C2=A0=C2=A0 char *string3=3D"Rotate String";
=C2=A0=C2=A0=C2=A0 char *string4=3D"Joy!!!";
=C2=A0=C2=A0=C2=A0=20
=C2=A0=C2=A0=C2=A0 cairo_surface_t *surface=3Dcairo_pdf_surface_create("cai=
ro_test1.pdf", width, height);
=C2=A0=C2=A0=C2=A0 cairo_t *cr=3Dcairo_create(surface);

=C2=A0=C2=A0=C2=A0 //Paint background.
=C2=A0=C2=A0=C2=A0 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
=C2=A0=C2=A0=C2=A0 cairo_paint(cr);

=C2=A0=C2=A0=C2=A0 //Draw from the center of surface. Good for testing text=
 and box alignment.
=C2=A0=C2=A0=C2=A0 cairo_translate(cr, width/2.0, height/2.0);
=C2=A0=C2=A0=C2=A0 //Scale the drawing if needed.
=C2=A0=C2=A0=C2=A0 cairo_scale(cr, 1.0, 1.0);

=C2=A0=C2=A0=C2=A0 //Draw cartesian coordinates.
=C2=A0=C2=A0=C2=A0 cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
=C2=A0=C2=A0=C2=A0 cairo_move_to(cr, -width/2.0, 0.0);
=C2=A0=C2=A0=C2=A0 cairo_line_to(cr, width/2.0, 0.0);
=C2=A0=C2=A0=C2=A0 cairo_stroke(cr);
=C2=A0=C2=A0=C2=A0 cairo_move_to(cr, 0.0, -height/2.0);
=C2=A0=C2=A0=C2=A0 cairo_line_to(cr, 0.0, height/2.0);
=C2=A0=C2=A0=C2=A0 cairo_stroke(cr);

=C2=A0=C2=A0=C2=A0 cairo_select_font_face(cr, "courier", CAIRO_FONT_SLANT_N=
ORMAL, CAIRO_FONT_WEIGHT_BOLD);
=C2=A0=C2=A0=C2=A0 //Since the font gets scaled to the box the default font=
 size should be fine.
=C2=A0=C2=A0=C2=A0 //cairo_set_font_size(cr, 10.0);

=C2=A0=C2=A0=C2=A0 //Draw text at center.
=C2=A0=C2=A0=C2=A0 text_in_box(cr, 0.0, 0.0, 350.0, 100.0, 0.0, string1);

=C2=A0=C2=A0=C2=A0 //Translate text.
=C2=A0=C2=A0=C2=A0 text_in_box(cr, -120.0, -150.0, 300.0, 30.0, 0.0, string=
2);

=C2=A0=C2=A0=C2=A0 //Rotate text.
=C2=A0=C2=A0=C2=A0 text_in_box(cr, 150.0, 150.0, 121.0, 52.0, M_PI/4.0, str=
ing3);

=C2=A0=C2=A0=C2=A0 text_in_box(cr, -150.0, 185.0, 121.0, 52.0, -M_PI/4.0, s=
tring4);

=C2=A0=C2=A0=C2=A0 text_in_box(cr, 150.0, -190.0, 225.0, 52.0, -M_PI/4.0, s=
tring4);
=C2=A0=C2=A0=20
=C2=A0=C2=A0=C2=A0 printf("Output to cairo_test1.pdf\n");

=C2=A0=C2=A0=C2=A0 cairo_destroy(cr);
=C2=A0=C2=A0=C2=A0 cairo_surface_destroy(surface);

=C2=A0=C2=A0=C2=A0 return 0;
=C2=A0 }
static void text_in_box(cairo_t *cr, double center_box_x, double center_box=
_y, double box_width, double box_height, double rotate, char *string)
=C2=A0 {
=C2=A0=C2=A0=C2=A0 double move_x=3D0.0;
=C2=A0=C2=A0=C2=A0 double move_y=3D0.0;
=C2=A0=C2=A0=C2=A0 double scale_x=3D0.0;
=C2=A0=C2=A0=C2=A0 double scale_y=3D0.0;
=C2=A0=C2=A0=C2=A0 cairo_text_extents_t te;
=C2=A0=C2=A0=C2=A0 cairo_font_extents_t fe;

=C2=A0=C2=A0=C2=A0 //Get some font metrics.
=C2=A0=C2=A0=C2=A0 cairo_text_extents(cr, string, &te);
=C2=A0=C2=A0=C2=A0 cairo_font_extents(cr, &fe);
=C2=A0=C2=A0=C2=A0 move_x=3D-te.width/2.0-te.x_bearing;
=C2=A0=C2=A0=C2=A0 move_y=3D-te.height/2.0-te.y_bearing;
=C2=A0=C2=A0=C2=A0 //Pad the rectangle a little.
=C2=A0=C2=A0=C2=A0 scale_x=3D-te.width/2.0-te.x_bearing-4.0;
=C2=A0=C2=A0=C2=A0 scale_y=3D-te.height/2.0-te.y_bearing+fe.descent;
=C2=A0=C2=A0=20
=C2=A0=C2=A0=C2=A0 //Order transforms and draw.
=C2=A0=C2=A0=C2=A0 cairo_save(cr);
=C2=A0=C2=A0=C2=A0 cairo_translate(cr, center_box_x, center_box_y);
=C2=A0=C2=A0=C2=A0 cairo_rotate(cr, rotate);
=C2=A0=C2=A0=C2=A0 cairo_scale(cr, box_width/fabs(2.0*move_x), box_height/f=
abs(2.0*move_y));
=C2=A0=C2=A0=C2=A0 cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.4);
=C2=A0=C2=A0=C2=A0 cairo_rectangle(cr, -fabs(scale_x), -fabs(scale_y), fabs=
(2.0*scale_x), fabs(2.0*scale_y));
=C2=A0=C2=A0=C2=A0 cairo_fill(cr);=20
=C2=A0=C2=A0=C2=A0 cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
=C2=A0=C2=A0=C2=A0 cairo_move_to(cr, move_x, move_y);
=C2=A0=C2=A0=C2=A0 cairo_show_text(cr, string);
=C2=A0=C2=A0=C2=A0 cairo_restore(cr);=20
=C2=A0 }

=20


------=_Part_2814875_1393427384.1556646482267
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 7bit

<font color='black' size='2' face='arial'>
<div> <font size="2"><br>
Hi Warren,<br>
<br>
Have you made some progress with this?<br>
<br>
Well, you might need some font metrics and get the transforms in order to be able to do this. The following is in C but it might be helpful. Probably need to change a few things around but it is a start.<br>
<br>
Eric <br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
//gcc -Wall cairo_text_size.c -o cairo_text_size `pkg-config --cflags --libs cairo` -lm<br>
<br>
#include&lt;cairo.h&gt;<br>
#include&lt;cairo-pdf.h&gt;<br>
#include&lt;stdio.h&gt;<br>
#include&lt;math.h&gt;<br>
<br>
static void text_in_box(cairo_t *cr, double center_box_x, double center_box_y, double box_width, double box_height, double rotate, char *string);<br>
<br>
int main()<br>
&nbsp; {<br>
&nbsp;&nbsp;&nbsp; double width=600.0;<br>
&nbsp;&nbsp;&nbsp; double height=600.0;<br>
&nbsp;&nbsp;&nbsp; char *string1="Center String";<br>
&nbsp;&nbsp;&nbsp; char *string2="Translate Stringssssss!";<br>
&nbsp;&nbsp;&nbsp; char *string3="Rotate String";<br>
&nbsp;&nbsp;&nbsp; char *string4="Joy!!!";<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; cairo_surface_t *surface=cairo_pdf_surface_create("cairo_test1.pdf", width, height);<br>
&nbsp;&nbsp;&nbsp; cairo_t *cr=cairo_create(surface);<br>
<br>
&nbsp;&nbsp;&nbsp; //Paint background.<br>
&nbsp;&nbsp;&nbsp; cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);<br>
&nbsp;&nbsp;&nbsp; cairo_paint(cr);<br>
<br>
&nbsp;&nbsp;&nbsp; //Draw from the center of surface. Good for testing text and box alignment.<br>
&nbsp;&nbsp;&nbsp; cairo_translate(cr, width/2.0, height/2.0);<br>
&nbsp;&nbsp;&nbsp; //Scale the drawing if needed.<br>
&nbsp;&nbsp;&nbsp; cairo_scale(cr, 1.0, 1.0);<br>
<br>
&nbsp;&nbsp;&nbsp; //Draw cartesian coordinates.<br>
&nbsp;&nbsp;&nbsp; cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);<br>
&nbsp;&nbsp;&nbsp; cairo_move_to(cr, -width/2.0, 0.0);<br>
&nbsp;&nbsp;&nbsp; cairo_line_to(cr, width/2.0, 0.0);<br>
&nbsp;&nbsp;&nbsp; cairo_stroke(cr);<br>
&nbsp;&nbsp;&nbsp; cairo_move_to(cr, 0.0, -height/2.0);<br>
&nbsp;&nbsp;&nbsp; cairo_line_to(cr, 0.0, height/2.0);<br>
&nbsp;&nbsp;&nbsp; cairo_stroke(cr);<br>
<br>
&nbsp;&nbsp;&nbsp; cairo_select_font_face(cr, "courier", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);<br>
&nbsp;&nbsp;&nbsp; //Since the font gets scaled to the box the default font size should be fine.<br>
&nbsp;&nbsp;&nbsp; //cairo_set_font_size(cr, 10.0);<br>
<br>
&nbsp;&nbsp;&nbsp; //Draw text at center.<br>
&nbsp;&nbsp;&nbsp; text_in_box(cr, 0.0, 0.0, 350.0, 100.0, 0.0, string1);<br>
<br>
&nbsp;&nbsp;&nbsp; //Translate text.<br>
&nbsp;&nbsp;&nbsp; text_in_box(cr, -120.0, -150.0, 300.0, 30.0, 0.0, string2);<br>
<br>
&nbsp;&nbsp;&nbsp; //Rotate text.<br>
&nbsp;&nbsp;&nbsp; text_in_box(cr, 150.0, 150.0, 121.0, 52.0, M_PI/4.0, string3);<br>
<br>
&nbsp;&nbsp;&nbsp; text_in_box(cr, -150.0, 185.0, 121.0, 52.0, -M_PI/4.0, string4);<br>
<br>
&nbsp;&nbsp;&nbsp; text_in_box(cr, 150.0, -190.0, 225.0, 52.0, -M_PI/4.0, string4);<br>
&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; printf("Output to cairo_test1.pdf\n");<br>
<br>
&nbsp;&nbsp;&nbsp; cairo_destroy(cr);<br>
&nbsp;&nbsp;&nbsp; cairo_surface_destroy(surface);<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
&nbsp; }<br>
static void text_in_box(cairo_t *cr, double center_box_x, double center_box_y, double box_width, double box_height, double rotate, char *string)<br>
&nbsp; {<br>
&nbsp;&nbsp;&nbsp; double move_x=0.0;<br>
&nbsp;&nbsp;&nbsp; double move_y=0.0;<br>
&nbsp;&nbsp;&nbsp; double scale_x=0.0;<br>
&nbsp;&nbsp;&nbsp; double scale_y=0.0;<br>
&nbsp;&nbsp;&nbsp; cairo_text_extents_t te;<br>
&nbsp;&nbsp;&nbsp; cairo_font_extents_t fe;<br>
<br>
&nbsp;&nbsp;&nbsp; //Get some font metrics.<br>
&nbsp;&nbsp;&nbsp; cairo_text_extents(cr, string, &amp;te);<br>
&nbsp;&nbsp;&nbsp; cairo_font_extents(cr, &amp;fe);<br>
&nbsp;&nbsp;&nbsp; move_x=-te.width/2.0-te.x_bearing;<br>
&nbsp;&nbsp;&nbsp; move_y=-te.height/2.0-te.y_bearing;<br>
&nbsp;&nbsp;&nbsp; //Pad the rectangle a little.<br>
&nbsp;&nbsp;&nbsp; scale_x=-te.width/2.0-te.x_bearing-4.0;<br>
&nbsp;&nbsp;&nbsp; scale_y=-te.height/2.0-te.y_bearing+fe.descent;<br>
&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; //Order transforms and draw.<br>
&nbsp;&nbsp;&nbsp; cairo_save(cr);<br>
&nbsp;&nbsp;&nbsp; cairo_translate(cr, center_box_x, center_box_y);<br>
&nbsp;&nbsp;&nbsp; cairo_rotate(cr, rotate);<br>
&nbsp;&nbsp;&nbsp; cairo_scale(cr, box_width/fabs(2.0*move_x), box_height/fabs(2.0*move_y));<br>
&nbsp;&nbsp;&nbsp; cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.4);<br>
&nbsp;&nbsp;&nbsp; cairo_rectangle(cr, -fabs(scale_x), -fabs(scale_y), fabs(2.0*scale_x), fabs(2.0*scale_y));<br>
&nbsp;&nbsp;&nbsp; cairo_fill(cr); <br>
&nbsp;&nbsp;&nbsp; cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);<br>
&nbsp;&nbsp;&nbsp; cairo_move_to(cr, move_x, move_y);<br>
&nbsp;&nbsp;&nbsp; cairo_show_text(cr, string);<br>
&nbsp;&nbsp;&nbsp; cairo_restore(cr); <br>
&nbsp; }<br>
</font><br>
</div>

<div> <br>
</div>
<br>
</font>
------=_Part_2814875_1393427384.1556646482267--

--===============1811114430==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

LS0gCmNhaXJvIG1haWxpbmcgbGlzdApjYWlyb0BjYWlyb2dyYXBoaWNzLm9yZwpodHRwczovL2xp
c3RzLmNhaXJvZ3JhcGhpY3Mub3JnL21haWxtYW4vbGlzdGluZm8vY2Fpcm8=

--===============1811114430==--