]> git.sur5r.net Git - glabels/blob - src/cairo-markup-path.c
Imported Upstream version 2.2.8
[glabels] / src / cairo-markup-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_markup_path.c:  Cairo markup 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-markup-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_markup_margin_path         (cairo_t                 *cr,
47                                                        const lglTemplateMarkup *markup,
48                                                        glLabel                 *label);
49
50 static void       gl_cairo_markup_margin_rect_path    (cairo_t                 *cr,
51                                                        const lglTemplateMarkup *markup,
52                                                        glLabel                 *label);
53
54 static void       gl_cairo_markup_margin_round_path   (cairo_t                 *cr,
55                                                        const lglTemplateMarkup *markup,
56                                                        glLabel                 *label);
57
58 static void       gl_cairo_markup_margin_cd_path      (cairo_t                 *cr,
59                                                        const lglTemplateMarkup *markup,
60                                                        glLabel                 *label);
61
62 static void       gl_cairo_markup_line_path           (cairo_t                 *cr,
63                                                        const lglTemplateMarkup *markup);
64
65 static void       gl_cairo_markup_circle_path         (cairo_t                 *cr,
66                                                        const lglTemplateMarkup *markup);
67
68 static void       gl_cairo_markup_rect_path           (cairo_t                 *cr,
69                                                        const lglTemplateMarkup *markup);
70
71 \f
72 /*--------------------------------------------------------------------------*/
73 /* Create markup path                                                       */
74 /*--------------------------------------------------------------------------*/
75 void
76 gl_cairo_markup_path (cairo_t                 *cr,
77                       const lglTemplateMarkup *markup,
78                       glLabel                 *label)
79 {
80         gl_debug (DEBUG_PATH, "START");
81
82         switch (markup->type) {
83         case LGL_TEMPLATE_MARKUP_MARGIN:
84                 gl_cairo_markup_margin_path (cr, markup, label);
85                 break;
86         case LGL_TEMPLATE_MARKUP_LINE:
87                 gl_cairo_markup_line_path (cr, markup);
88                 break;
89         case LGL_TEMPLATE_MARKUP_CIRCLE:
90                 gl_cairo_markup_circle_path (cr, markup);
91                 break;
92         case LGL_TEMPLATE_MARKUP_RECT:
93                 gl_cairo_markup_rect_path (cr, markup);
94                 break;
95         default:
96                 g_message ("Unknown template markup type");
97                 break;
98         }
99
100         gl_debug (DEBUG_PATH, "END");
101 }
102
103 /*---------------------------------------------------------------------------*/
104 /* PRIVATE.  Draw margin markup.                                             */
105 /*---------------------------------------------------------------------------*/
106 static void
107 gl_cairo_markup_margin_path (cairo_t                *cr,
108                              const lglTemplateMarkup *markup,
109                              glLabel                *label)
110 {
111         const lglTemplateFrame *frame;
112
113         gl_debug (DEBUG_PATH, "START");
114
115         frame = (lglTemplateFrame *)label->template->frames->data;
116
117         switch (frame->shape) {
118
119         case LGL_TEMPLATE_FRAME_SHAPE_RECT:
120                 gl_cairo_markup_margin_rect_path (cr, markup, label);
121                 break;
122
123         case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
124                 gl_cairo_markup_margin_round_path (cr, markup, label);
125                 break;
126
127         case LGL_TEMPLATE_FRAME_SHAPE_CD:
128                 gl_cairo_markup_margin_cd_path (cr, markup, label);
129                 break;
130
131         default:
132                 g_message ("Unknown template label style");
133                 break;
134         }
135
136         gl_debug (DEBUG_PATH, "END");
137 }
138
139 /*---------------------------------------------------------------------------*/
140 /* PRIVATE.  Draw simple recangular margin.                                  */
141 /*---------------------------------------------------------------------------*/
142 static void
143 gl_cairo_markup_margin_rect_path (cairo_t                 *cr,
144                                   const lglTemplateMarkup *markup,
145                                   glLabel                 *label)
146 {
147         const lglTemplateFrame *frame;
148         gdouble                 w, h, r, m;
149
150         gl_debug (DEBUG_PATH, "START");
151
152         frame = (lglTemplateFrame *)label->template->frames->data;
153
154         m = markup->margin.size;
155
156         lgl_template_frame_get_size (frame, &w, &h);
157         w = w - 2*m;
158         h = h - 2*m;
159         r = MAX (frame->rect.r - m, 0.0);
160
161         if ( r == 0.0 )
162         {
163                 cairo_rectangle (cr, m, m, w, h);
164         }
165         else
166         {
167                 cairo_new_path (cr);
168                 cairo_arc_negative (cr, m+r,   m+r,   r, 3*G_PI/2, G_PI);
169                 cairo_arc_negative (cr, m+r,   m+h-r, r, G_PI,     G_PI/2);
170                 cairo_arc_negative (cr, m+w-r, m+h-r, r, G_PI/2,   0.);
171                 cairo_arc_negative (cr, m+w-r, m+r,   r, 2*G_PI,   3*G_PI/2);
172                 cairo_close_path (cr);
173         }
174
175         gl_debug (DEBUG_PATH, "END");
176 }
177
178 /*---------------------------------------------------------------------------*/
179 /* PRIVATE.  Draw round margin.                                              */
180 /*---------------------------------------------------------------------------*/
181 static void
182 gl_cairo_markup_margin_round_path (cairo_t                 *cr,
183                                    const lglTemplateMarkup *markup,
184                                    glLabel                 *label)
185 {
186         const lglTemplateFrame *frame;
187         gdouble                 r, m;
188
189         gl_debug (DEBUG_PATH, "START");
190
191         frame = (lglTemplateFrame *)label->template->frames->data;
192
193         r = frame->round.r;
194         m = markup->margin.size;
195
196         cairo_arc (cr, r, r, r-m, 0, 2*G_PI);
197         cairo_close_path (cr);
198
199         gl_debug (DEBUG_PATH, "END");
200 }
201
202 /*---------------------------------------------------------------------------*/
203 /* PRIVATE.  Draw CD margins.                                                */
204 /*---------------------------------------------------------------------------*/
205 static void
206 gl_cairo_markup_margin_cd_path (cairo_t                 *cr,
207                                 const lglTemplateMarkup *markup,
208                                 glLabel                 *label)
209 {
210         const lglTemplateFrame *frame;
211         gdouble                 m, r1, r2;
212         gdouble                 theta1, theta2;
213         gdouble                 xc, yc;
214         gdouble                 w, h;
215
216         gl_debug (DEBUG_PATH, "START");
217
218         frame = (lglTemplateFrame *)label->template->frames->data;
219
220         lgl_template_frame_get_size (frame, &w, &h);
221         xc = w/2.0;
222         yc = h/2.0;
223
224         m  = markup->margin.size;
225         r1 = frame->cd.r1 - m;
226         r2 = frame->cd.r2 + m;
227
228
229         /*
230          * Outer path (may be clipped)
231          */
232         theta1 = acos ((w-2*m) / (2.0*r1));
233         theta2 = asin ((h-2*m) / (2.0*r1));
234
235         cairo_new_path (cr);
236         cairo_arc (cr, xc, yc, r1, theta1, theta2);
237         cairo_arc (cr, xc, yc, r1, G_PI-theta2, G_PI-theta1);
238         cairo_arc (cr, xc, yc, r1, G_PI+theta1, G_PI+theta2);
239         cairo_arc (cr, xc, yc, r1, 2*G_PI-theta2, 2*G_PI-theta1);
240         cairo_close_path (cr);
241
242
243         /* Inner path (hole) */
244         cairo_new_sub_path (cr);
245         cairo_arc (cr, xc, yc, r2, 0.0, 2*G_PI);
246         cairo_close_path (cr);
247
248         gl_debug (DEBUG_PATH, "END");
249 }
250
251 /*---------------------------------------------------------------------------*/
252 /* PRIVATE.  Draw line markup.                                               */
253 /*---------------------------------------------------------------------------*/
254 static void
255 gl_cairo_markup_line_path (cairo_t                 *cr,
256                            const lglTemplateMarkup *markup)
257 {
258         gl_debug (DEBUG_PATH, "START");
259
260         cairo_move_to (cr, markup->line.x1, markup->line.y1);
261         cairo_line_to (cr, markup->line.x2, markup->line.y2);
262
263         gl_debug (DEBUG_PATH, "END");
264 }
265
266 /*---------------------------------------------------------------------------*/
267 /* PRIVATE.  Draw circle markup.                                             */
268 /*---------------------------------------------------------------------------*/
269 static void
270 gl_cairo_markup_circle_path (cairo_t                 *cr,
271                              const lglTemplateMarkup *markup)
272 {
273         gl_debug (DEBUG_PATH, "START");
274
275         cairo_arc (cr,
276                    markup->circle.x0, markup->circle.y0,
277                    markup->circle.r,
278                    0.0, 2*G_PI);
279         cairo_close_path (cr);
280
281         gl_debug (DEBUG_PATH, "END");
282 }
283
284 /*---------------------------------------------------------------------------*/
285 /* PRIVATE.  Draw rect markup.                                               */
286 /*---------------------------------------------------------------------------*/
287 static void
288 gl_cairo_markup_rect_path (cairo_t                 *cr,
289                            const lglTemplateMarkup *markup)
290 {
291         gdouble x1 = markup->rect.x1;
292         gdouble y1 = markup->rect.y1;
293         gdouble w  = markup->rect.w;
294         gdouble h  = markup->rect.h;
295         gdouble r  = markup->rect.r;
296
297         gl_debug (DEBUG_PATH, "START");
298
299         if ( r == 0.0 )
300         {
301                 cairo_rectangle (cr, x1, y1, w, h);
302         }
303         else
304         {
305                 cairo_new_path (cr);
306                 cairo_arc_negative (cr, x1+r,   y1+r,   r, 3*G_PI/2, G_PI);
307                 cairo_arc_negative (cr, x1+r,   y1+h-r, r, G_PI,     G_PI/2);
308                 cairo_arc_negative (cr, x1+w-r, y1+h-r, r, G_PI/2,   0.);
309                 cairo_arc_negative (cr, x1+w-r, y1+r,   r, 2*G_PI,   3*G_PI/2);
310                 cairo_close_path (cr);
311         }
312
313         gl_debug (DEBUG_PATH, "END");
314 }
315