]> git.sur5r.net Git - glabels/blob - src/cairo-label-path.c
Imported Upstream version 2.2.8
[glabels] / src / cairo-label-path.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 /*
4  *  (GLABELS) Label and Business Card Creation program for GNOME
5  *
6  *  cairo_label_path.c:  Cairo label path module
7  *
8  *  Copyright (C) 2001-2007  Jim Evins <evins@snaught.com>.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  */
24
25 #include <config.h>
26
27 #include "cairo-label-path.h"
28
29 #include <math.h>
30 #include <glib.h>
31
32 #include "debug.h"
33
34 /*===========================================*/
35 /* Private types                             */
36 /*===========================================*/
37
38 /*===========================================*/
39 /* Private globals                           */
40 /*===========================================*/
41
42 /*===========================================*/
43 /* Local function prototypes                 */
44 /*===========================================*/
45
46 static void gl_cairo_rect_label_path             (cairo_t                *cr,
47                                                   lglTemplate            *template,
48                                                   gboolean                rotate_flag,
49                                                   gboolean                waste_flag);
50 static void gl_cairo_round_label_path            (cairo_t                *cr,
51                                                   lglTemplate            *template,
52                                                   gboolean                rotate_flag,
53                                                   gboolean                waste_flag);
54 static void gl_cairo_cd_label_path               (cairo_t                *cr,
55                                                   lglTemplate            *template,
56                                                   gboolean                rotate_flag,
57                                                   gboolean                waste_flag);
58
59 \f
60 /*--------------------------------------------------------------------------*/
61 /* Create label path                                                        */
62 /*--------------------------------------------------------------------------*/
63 void
64 gl_cairo_label_path (cairo_t           *cr,
65                      lglTemplate       *template,
66                      gboolean           rotate_flag,
67                      gboolean           waste_flag)
68 {
69         const lglTemplateFrame *frame;
70
71         gl_debug (DEBUG_PATH, "START");
72
73         frame = (lglTemplateFrame *)template->frames->data;
74
75         switch (frame->shape) {
76
77         case LGL_TEMPLATE_FRAME_SHAPE_RECT:
78                 gl_cairo_rect_label_path (cr, template, rotate_flag, waste_flag);
79                 break;
80
81         case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
82                 gl_cairo_round_label_path (cr, template, rotate_flag, waste_flag);
83                 break;
84
85         case LGL_TEMPLATE_FRAME_SHAPE_CD:
86                 gl_cairo_cd_label_path (cr, template, rotate_flag, waste_flag);
87                 break;
88
89         default:
90                 g_message ("Unknown label style");
91                 break;
92         }
93
94         gl_debug (DEBUG_PATH, "END");
95 }
96
97 /*--------------------------------------------------------------------------*/
98 /* Create rectangular label path                                            */
99 /*--------------------------------------------------------------------------*/
100 static void
101 gl_cairo_rect_label_path (cairo_t           *cr,
102                           lglTemplate       *template,
103                           gboolean           rotate_flag,
104                           gboolean           waste_flag)
105 {
106         const lglTemplateFrame *frame;
107         gdouble                 w, h, r;
108         gdouble                 x_waste, y_waste;
109
110         gl_debug (DEBUG_PATH, "START");
111
112         frame = (lglTemplateFrame *)template->frames->data;
113         r = frame->rect.r;
114
115         x_waste = 0.0;
116         y_waste = 0.0;
117
118         if (rotate_flag)
119         {
120                 lgl_template_frame_get_size (frame, &h, &w);
121                 if (waste_flag)
122                 {
123                         x_waste = frame->rect.y_waste;
124                         y_waste = frame->rect.x_waste;
125                 }
126         }
127         else
128         {
129                 lgl_template_frame_get_size (frame, &w, &h);
130                 if (waste_flag)
131                 {
132                         x_waste = frame->rect.x_waste;
133                         y_waste = frame->rect.y_waste;
134                 }
135         }
136
137
138         if ( r == 0.0 )
139         {
140                 cairo_rectangle (cr, -x_waste, -y_waste, w+x_waste, h+y_waste);
141         }
142         else
143         {
144                 cairo_new_path (cr);
145                 cairo_arc_negative (cr, r-x_waste,   r-y_waste,   r, 3*G_PI/2, G_PI);
146                 cairo_arc_negative (cr, r-x_waste,   h-r+y_waste, r, G_PI,     G_PI/2);
147                 cairo_arc_negative (cr, w-r+x_waste, h-r+y_waste, r, G_PI/2,   0.);
148                 cairo_arc_negative (cr, w-r+x_waste, r-y_waste,   r, 2*G_PI,   3*G_PI/2);
149                 cairo_close_path (cr);
150         }
151
152         gl_debug (DEBUG_PATH, "END");
153 }
154
155 /*--------------------------------------------------------------------------*/
156 /* Create round label path                                                  */
157 /*--------------------------------------------------------------------------*/
158 static void
159 gl_cairo_round_label_path (cairo_t           *cr,
160                            lglTemplate       *template,
161                            gboolean           rotate_flag,
162                            gboolean           waste_flag)
163 {
164         const lglTemplateFrame *frame;
165         gdouble                 w, h;
166         gdouble                 waste;
167
168         gl_debug (DEBUG_PATH, "START");
169
170         frame = (lglTemplateFrame *)template->frames->data;
171         
172         if (rotate_flag)
173         {
174                 lgl_template_frame_get_size (frame, &h, &w);
175         }
176         else
177         {
178                 lgl_template_frame_get_size (frame, &w, &h);
179         }
180
181         if (waste_flag)
182         {
183                 waste = frame->round.waste;
184         }
185         else
186         {
187                 waste = 0.0;
188         }
189
190         cairo_new_path (cr);
191         cairo_arc (cr, w/2, h/2, w/2+waste, 0.0, 2*G_PI);
192         cairo_close_path (cr);
193
194         gl_debug (DEBUG_PATH, "END");
195 }
196
197 /*--------------------------------------------------------------------------*/
198 /* Create cd label path                                                     */
199 /*--------------------------------------------------------------------------*/
200 static void
201 gl_cairo_cd_label_path (cairo_t           *cr,
202                         lglTemplate       *template,
203                         gboolean           rotate_flag,
204                         gboolean           waste_flag)
205 {
206         const lglTemplateFrame *frame;
207         gdouble                 w, h;
208         gdouble                 xc, yc;
209         gdouble                 r1, r2;
210         gdouble                 theta1, theta2;
211         gdouble                 waste;
212
213         gl_debug (DEBUG_PATH, "START");
214
215         frame = (lglTemplateFrame *)template->frames->data;
216
217         if (rotate_flag)
218         {
219                 lgl_template_frame_get_size (frame, &h, &w);
220         }
221         else
222         {
223                 lgl_template_frame_get_size (frame, &w, &h);
224         }
225
226         xc = w/2.0;
227         yc = h/2.0;
228
229         r1 = frame->cd.r1;
230         r2 = frame->cd.r2;
231
232         if (waste_flag)
233         {
234                 waste = frame->cd.waste;
235         }
236         else
237         {
238                 waste = 0.0;
239         }
240
241         /*
242          * Outer path (may be clipped in the case of a business card type CD)
243          */
244         theta1 = acos (w / (2.0*r1));
245         theta2 = asin (h / (2.0*r1));
246
247         cairo_new_path (cr);
248         cairo_arc (cr, xc, yc, r1+waste, theta1, theta2);
249         cairo_arc (cr, xc, yc, r1+waste, G_PI-theta2, G_PI-theta1);
250         cairo_arc (cr, xc, yc, r1+waste, G_PI+theta1, G_PI+theta2);
251         cairo_arc (cr, xc, yc, r1+waste, 2*G_PI-theta2, 2*G_PI-theta1);
252         cairo_close_path (cr);
253
254
255         /*
256          * Inner path (hole)
257          */
258         cairo_new_sub_path (cr);
259         cairo_arc (cr, xc, yc, r2-waste, 0.0, 2*G_PI);
260         cairo_close_path (cr);
261
262         gl_debug (DEBUG_PATH, "END");
263 }
264