]> git.sur5r.net Git - glabels/blob - src/cairo-markup-path.c
Upload to unstable
[glabels] / src / cairo-markup-path.c
1 /*
2  *  cairo-markup-path.c
3  *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
7  *  gLabels is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  gLabels is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include "cairo-markup-path.h"
24
25 #include <math.h>
26
27 #include "cairo-ellipse-path.h"
28
29 #include "debug.h"
30
31
32 /*===========================================*/
33 /* Private types                             */
34 /*===========================================*/
35
36
37 /*===========================================*/
38 /* Private globals                           */
39 /*===========================================*/
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_ellipse_path (cairo_t                 *cr,
55                                                        const lglTemplateMarkup *markup,
56                                                        glLabel                 *label);
57
58 static void       gl_cairo_markup_margin_round_path   (cairo_t                 *cr,
59                                                        const lglTemplateMarkup *markup,
60                                                        glLabel                 *label);
61
62 static void       gl_cairo_markup_margin_cd_path      (cairo_t                 *cr,
63                                                        const lglTemplateMarkup *markup,
64                                                        glLabel                 *label);
65
66 static void       gl_cairo_markup_line_path           (cairo_t                 *cr,
67                                                        const lglTemplateMarkup *markup);
68
69 static void       gl_cairo_markup_circle_path         (cairo_t                 *cr,
70                                                        const lglTemplateMarkup *markup);
71
72 static void       gl_cairo_markup_rect_path           (cairo_t                 *cr,
73                                                        const lglTemplateMarkup *markup);
74
75 static void       gl_cairo_markup_ellipse_path        (cairo_t                 *cr,
76                                                        const lglTemplateMarkup *markup);
77
78
79 /*--------------------------------------------------------------------------*/
80 /* Create markup path                                                       */
81 /*--------------------------------------------------------------------------*/
82 void
83 gl_cairo_markup_path (cairo_t                 *cr,
84                       const lglTemplateMarkup *markup,
85                       glLabel                 *label)
86 {
87         gl_debug (DEBUG_PATH, "START");
88
89         switch (markup->type) {
90         case LGL_TEMPLATE_MARKUP_MARGIN:
91                 gl_cairo_markup_margin_path (cr, markup, label);
92                 break;
93         case LGL_TEMPLATE_MARKUP_LINE:
94                 gl_cairo_markup_line_path (cr, markup);
95                 break;
96         case LGL_TEMPLATE_MARKUP_CIRCLE:
97                 gl_cairo_markup_circle_path (cr, markup);
98                 break;
99         case LGL_TEMPLATE_MARKUP_RECT:
100                 gl_cairo_markup_rect_path (cr, markup);
101                 break;
102         case LGL_TEMPLATE_MARKUP_ELLIPSE:
103                 gl_cairo_markup_ellipse_path (cr, markup);
104                 break;
105         default:
106                 g_message ("Unknown template markup type");
107                 break;
108         }
109
110         gl_debug (DEBUG_PATH, "END");
111 }
112
113
114 /*---------------------------------------------------------------------------*/
115 /* PRIVATE.  Draw margin markup.                                             */
116 /*---------------------------------------------------------------------------*/
117 static void
118 gl_cairo_markup_margin_path (cairo_t                *cr,
119                              const lglTemplateMarkup *markup,
120                              glLabel                *label)
121 {
122         const lglTemplate      *template;
123         const lglTemplateFrame *frame;
124
125         gl_debug (DEBUG_PATH, "START");
126
127         template = gl_label_get_template (label);
128         frame = (lglTemplateFrame *)template->frames->data;
129
130         switch (frame->shape) {
131
132         case LGL_TEMPLATE_FRAME_SHAPE_RECT:
133                 gl_cairo_markup_margin_rect_path (cr, markup, label);
134                 break;
135
136         case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
137                 gl_cairo_markup_margin_ellipse_path (cr, markup, label);
138                 break;
139
140         case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
141                 gl_cairo_markup_margin_round_path (cr, markup, label);
142                 break;
143
144         case LGL_TEMPLATE_FRAME_SHAPE_CD:
145                 gl_cairo_markup_margin_cd_path (cr, markup, label);
146                 break;
147
148         default:
149                 g_message ("Unknown template label style");
150                 break;
151         }
152
153         gl_debug (DEBUG_PATH, "END");
154 }
155
156
157 /*---------------------------------------------------------------------------*/
158 /* PRIVATE.  Draw simple recangular margin.                                  */
159 /*---------------------------------------------------------------------------*/
160 static void
161 gl_cairo_markup_margin_rect_path (cairo_t                 *cr,
162                                   const lglTemplateMarkup *markup,
163                                   glLabel                 *label)
164 {
165         const lglTemplate      *template;
166         const lglTemplateFrame *frame;
167         gdouble                 w, h, r, m;
168
169         gl_debug (DEBUG_PATH, "START");
170
171         template = gl_label_get_template (label);
172         frame = (lglTemplateFrame *)template->frames->data;
173
174         m = markup->margin.size;
175
176         lgl_template_frame_get_size (frame, &w, &h);
177         w = w - 2*m;
178         h = h - 2*m;
179         r = MAX (frame->rect.r - m, 0.0);
180
181         if ( r == 0.0 )
182         {
183                 cairo_rectangle (cr, m, m, w, h);
184         }
185         else
186         {
187                 cairo_new_path (cr);
188                 cairo_arc_negative (cr, m+r,   m+r,   r, 3*G_PI/2, G_PI);
189                 cairo_arc_negative (cr, m+r,   m+h-r, r, G_PI,     G_PI/2);
190                 cairo_arc_negative (cr, m+w-r, m+h-r, r, G_PI/2,   0.);
191                 cairo_arc_negative (cr, m+w-r, m+r,   r, 2*G_PI,   3*G_PI/2);
192                 cairo_close_path (cr);
193         }
194
195         gl_debug (DEBUG_PATH, "END");
196 }
197
198
199 /*---------------------------------------------------------------------------*/
200 /* PRIVATE.  Draw elliptical margin.                                         */
201 /*---------------------------------------------------------------------------*/
202 static void
203 gl_cairo_markup_margin_ellipse_path (cairo_t                 *cr,
204                                      const lglTemplateMarkup *markup,
205                                      glLabel                 *label)
206 {
207         const lglTemplate      *template;
208         const lglTemplateFrame *frame;
209         gdouble                 w, h, m;
210
211         gl_debug (DEBUG_PATH, "START");
212
213         template = gl_label_get_template (label);
214         frame = (lglTemplateFrame *)template->frames->data;
215
216         m = markup->margin.size;
217
218         lgl_template_frame_get_size (frame, &w, &h);
219         w = w - 2*m;
220         h = h - 2*m;
221
222         cairo_save (cr);
223         cairo_translate (cr, m, m);
224         gl_cairo_ellipse_path (cr, w/2.0, h/2.0);
225         cairo_restore (cr);
226
227         gl_debug (DEBUG_PATH, "END");
228 }
229
230
231 /*---------------------------------------------------------------------------*/
232 /* PRIVATE.  Draw round margin.                                              */
233 /*---------------------------------------------------------------------------*/
234 static void
235 gl_cairo_markup_margin_round_path (cairo_t                 *cr,
236                                    const lglTemplateMarkup *markup,
237                                    glLabel                 *label)
238 {
239         const lglTemplate      *template;
240         const lglTemplateFrame *frame;
241         gdouble                 r, m;
242
243         gl_debug (DEBUG_PATH, "START");
244
245         template = gl_label_get_template (label);
246         frame = (lglTemplateFrame *)template->frames->data;
247
248         r = frame->round.r;
249         m = markup->margin.size;
250
251         cairo_arc (cr, r, r, r-m, 0, 2*G_PI);
252         cairo_close_path (cr);
253
254         gl_debug (DEBUG_PATH, "END");
255 }
256
257
258 /*---------------------------------------------------------------------------*/
259 /* PRIVATE.  Draw CD margins.                                                */
260 /*---------------------------------------------------------------------------*/
261 static void
262 gl_cairo_markup_margin_cd_path (cairo_t                 *cr,
263                                 const lglTemplateMarkup *markup,
264                                 glLabel                 *label)
265 {
266         const lglTemplate      *template;
267         const lglTemplateFrame *frame;
268         gdouble                 m, r1, r2;
269         gdouble                 theta1, theta2;
270         gdouble                 xc, yc;
271         gdouble                 w, h;
272
273         gl_debug (DEBUG_PATH, "START");
274
275         template = gl_label_get_template (label);
276         frame = (lglTemplateFrame *)template->frames->data;
277
278         lgl_template_frame_get_size (frame, &w, &h);
279         xc = w/2.0;
280         yc = h/2.0;
281
282         m  = markup->margin.size;
283         r1 = frame->cd.r1 - m;
284         r2 = frame->cd.r2 + m;
285
286
287         /*
288          * Outer path (may be clipped)
289          */
290         theta1 = acos ((w-2*m) / (2.0*r1));
291         theta2 = asin ((h-2*m) / (2.0*r1));
292
293         cairo_new_path (cr);
294         cairo_arc (cr, xc, yc, r1, theta1, theta2);
295         cairo_arc (cr, xc, yc, r1, G_PI-theta2, G_PI-theta1);
296         cairo_arc (cr, xc, yc, r1, G_PI+theta1, G_PI+theta2);
297         cairo_arc (cr, xc, yc, r1, 2*G_PI-theta2, 2*G_PI-theta1);
298         cairo_close_path (cr);
299
300
301         /* Inner path (hole) */
302         cairo_new_sub_path (cr);
303         cairo_arc (cr, xc, yc, r2, 0.0, 2*G_PI);
304         cairo_close_path (cr);
305
306         gl_debug (DEBUG_PATH, "END");
307 }
308
309
310 /*---------------------------------------------------------------------------*/
311 /* PRIVATE.  Draw line markup.                                               */
312 /*---------------------------------------------------------------------------*/
313 static void
314 gl_cairo_markup_line_path (cairo_t                 *cr,
315                            const lglTemplateMarkup *markup)
316 {
317         gl_debug (DEBUG_PATH, "START");
318
319         cairo_move_to (cr, markup->line.x1, markup->line.y1);
320         cairo_line_to (cr, markup->line.x2, markup->line.y2);
321
322         gl_debug (DEBUG_PATH, "END");
323 }
324
325
326 /*---------------------------------------------------------------------------*/
327 /* PRIVATE.  Draw circle markup.                                             */
328 /*---------------------------------------------------------------------------*/
329 static void
330 gl_cairo_markup_circle_path (cairo_t                 *cr,
331                              const lglTemplateMarkup *markup)
332 {
333         gl_debug (DEBUG_PATH, "START");
334
335         cairo_arc (cr,
336                    markup->circle.x0, markup->circle.y0,
337                    markup->circle.r,
338                    0.0, 2*G_PI);
339         cairo_close_path (cr);
340
341         gl_debug (DEBUG_PATH, "END");
342 }
343
344
345 /*---------------------------------------------------------------------------*/
346 /* PRIVATE.  Draw rect markup.                                               */
347 /*---------------------------------------------------------------------------*/
348 static void
349 gl_cairo_markup_rect_path (cairo_t                 *cr,
350                            const lglTemplateMarkup *markup)
351 {
352         gdouble x1 = markup->rect.x1;
353         gdouble y1 = markup->rect.y1;
354         gdouble w  = markup->rect.w;
355         gdouble h  = markup->rect.h;
356         gdouble r  = markup->rect.r;
357
358         gl_debug (DEBUG_PATH, "START");
359
360         if ( r == 0.0 )
361         {
362                 cairo_rectangle (cr, x1, y1, w, h);
363         }
364         else
365         {
366                 cairo_new_path (cr);
367                 cairo_arc_negative (cr, x1+r,   y1+r,   r, 3*G_PI/2, G_PI);
368                 cairo_arc_negative (cr, x1+r,   y1+h-r, r, G_PI,     G_PI/2);
369                 cairo_arc_negative (cr, x1+w-r, y1+h-r, r, G_PI/2,   0.);
370                 cairo_arc_negative (cr, x1+w-r, y1+r,   r, 2*G_PI,   3*G_PI/2);
371                 cairo_close_path (cr);
372         }
373
374         gl_debug (DEBUG_PATH, "END");
375 }
376
377
378 /*---------------------------------------------------------------------------*/
379 /* PRIVATE.  Draw ellipse markup.                                            */
380 /*---------------------------------------------------------------------------*/
381 static void
382 gl_cairo_markup_ellipse_path (cairo_t                 *cr,
383                               const lglTemplateMarkup *markup)
384 {
385         gdouble x1 = markup->ellipse.x1;
386         gdouble y1 = markup->ellipse.y1;
387         gdouble w  = markup->ellipse.w;
388         gdouble h  = markup->ellipse.h;
389
390         gl_debug (DEBUG_PATH, "START");
391
392         cairo_save (cr);
393         cairo_translate (cr, x1, y1);
394         gl_cairo_ellipse_path (cr, w/2.0, h/2.0);
395         cairo_restore (cr);
396
397         gl_debug (DEBUG_PATH, "END");
398 }
399
400
401
402 /*
403  * Local Variables:       -- emacs
404  * mode: C                -- emacs
405  * c-basic-offset: 8      -- emacs
406  * tab-width: 8           -- emacs
407  * indent-tabs-mode: nil  -- emacs
408  * End:                   -- emacs
409  */