]> git.sur5r.net Git - glabels/blob - src/cairo-markup-path.c
Organized master branch to be top-level directory for glabels, instead of
[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 "debug.h"
28
29
30 /*===========================================*/
31 /* Private types                             */
32 /*===========================================*/
33
34
35 /*===========================================*/
36 /* Private globals                           */
37 /*===========================================*/
38
39
40 /*===========================================*/
41 /* Local function prototypes                 */
42 /*===========================================*/
43
44 static void       gl_cairo_markup_margin_path         (cairo_t                 *cr,
45                                                        const lglTemplateMarkup *markup,
46                                                        glLabel                 *label);
47
48 static void       gl_cairo_markup_margin_rect_path    (cairo_t                 *cr,
49                                                        const lglTemplateMarkup *markup,
50                                                        glLabel                 *label);
51
52 static void       gl_cairo_markup_margin_round_path   (cairo_t                 *cr,
53                                                        const lglTemplateMarkup *markup,
54                                                        glLabel                 *label);
55
56 static void       gl_cairo_markup_margin_cd_path      (cairo_t                 *cr,
57                                                        const lglTemplateMarkup *markup,
58                                                        glLabel                 *label);
59
60 static void       gl_cairo_markup_line_path           (cairo_t                 *cr,
61                                                        const lglTemplateMarkup *markup);
62
63 static void       gl_cairo_markup_circle_path         (cairo_t                 *cr,
64                                                        const lglTemplateMarkup *markup);
65
66 static void       gl_cairo_markup_rect_path           (cairo_t                 *cr,
67                                                        const lglTemplateMarkup *markup);
68
69
70 /*--------------------------------------------------------------------------*/
71 /* Create markup path                                                       */
72 /*--------------------------------------------------------------------------*/
73 void
74 gl_cairo_markup_path (cairo_t                 *cr,
75                       const lglTemplateMarkup *markup,
76                       glLabel                 *label)
77 {
78         gl_debug (DEBUG_PATH, "START");
79
80         switch (markup->type) {
81         case LGL_TEMPLATE_MARKUP_MARGIN:
82                 gl_cairo_markup_margin_path (cr, markup, label);
83                 break;
84         case LGL_TEMPLATE_MARKUP_LINE:
85                 gl_cairo_markup_line_path (cr, markup);
86                 break;
87         case LGL_TEMPLATE_MARKUP_CIRCLE:
88                 gl_cairo_markup_circle_path (cr, markup);
89                 break;
90         case LGL_TEMPLATE_MARKUP_RECT:
91                 gl_cairo_markup_rect_path (cr, markup);
92                 break;
93         default:
94                 g_message ("Unknown template markup type");
95                 break;
96         }
97
98         gl_debug (DEBUG_PATH, "END");
99 }
100
101
102 /*---------------------------------------------------------------------------*/
103 /* PRIVATE.  Draw margin markup.                                             */
104 /*---------------------------------------------------------------------------*/
105 static void
106 gl_cairo_markup_margin_path (cairo_t                *cr,
107                              const lglTemplateMarkup *markup,
108                              glLabel                *label)
109 {
110         const lglTemplateFrame *frame;
111
112         gl_debug (DEBUG_PATH, "START");
113
114         frame = (lglTemplateFrame *)label->template->frames->data;
115
116         switch (frame->shape) {
117
118         case LGL_TEMPLATE_FRAME_SHAPE_RECT:
119                 gl_cairo_markup_margin_rect_path (cr, markup, label);
120                 break;
121
122         case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
123                 gl_cairo_markup_margin_round_path (cr, markup, label);
124                 break;
125
126         case LGL_TEMPLATE_FRAME_SHAPE_CD:
127                 gl_cairo_markup_margin_cd_path (cr, markup, label);
128                 break;
129
130         default:
131                 g_message ("Unknown template label style");
132                 break;
133         }
134
135         gl_debug (DEBUG_PATH, "END");
136 }
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 /*---------------------------------------------------------------------------*/
180 /* PRIVATE.  Draw round margin.                                              */
181 /*---------------------------------------------------------------------------*/
182 static void
183 gl_cairo_markup_margin_round_path (cairo_t                 *cr,
184                                    const lglTemplateMarkup *markup,
185                                    glLabel                 *label)
186 {
187         const lglTemplateFrame *frame;
188         gdouble                 r, m;
189
190         gl_debug (DEBUG_PATH, "START");
191
192         frame = (lglTemplateFrame *)label->template->frames->data;
193
194         r = frame->round.r;
195         m = markup->margin.size;
196
197         cairo_arc (cr, r, r, r-m, 0, 2*G_PI);
198         cairo_close_path (cr);
199
200         gl_debug (DEBUG_PATH, "END");
201 }
202
203
204 /*---------------------------------------------------------------------------*/
205 /* PRIVATE.  Draw CD margins.                                                */
206 /*---------------------------------------------------------------------------*/
207 static void
208 gl_cairo_markup_margin_cd_path (cairo_t                 *cr,
209                                 const lglTemplateMarkup *markup,
210                                 glLabel                 *label)
211 {
212         const lglTemplateFrame *frame;
213         gdouble                 m, r1, r2;
214         gdouble                 theta1, theta2;
215         gdouble                 xc, yc;
216         gdouble                 w, h;
217
218         gl_debug (DEBUG_PATH, "START");
219
220         frame = (lglTemplateFrame *)label->template->frames->data;
221
222         lgl_template_frame_get_size (frame, &w, &h);
223         xc = w/2.0;
224         yc = h/2.0;
225
226         m  = markup->margin.size;
227         r1 = frame->cd.r1 - m;
228         r2 = frame->cd.r2 + m;
229
230
231         /*
232          * Outer path (may be clipped)
233          */
234         theta1 = acos ((w-2*m) / (2.0*r1));
235         theta2 = asin ((h-2*m) / (2.0*r1));
236
237         cairo_new_path (cr);
238         cairo_arc (cr, xc, yc, r1, theta1, theta2);
239         cairo_arc (cr, xc, yc, r1, G_PI-theta2, G_PI-theta1);
240         cairo_arc (cr, xc, yc, r1, G_PI+theta1, G_PI+theta2);
241         cairo_arc (cr, xc, yc, r1, 2*G_PI-theta2, 2*G_PI-theta1);
242         cairo_close_path (cr);
243
244
245         /* Inner path (hole) */
246         cairo_new_sub_path (cr);
247         cairo_arc (cr, xc, yc, r2, 0.0, 2*G_PI);
248         cairo_close_path (cr);
249
250         gl_debug (DEBUG_PATH, "END");
251 }
252
253
254 /*---------------------------------------------------------------------------*/
255 /* PRIVATE.  Draw line markup.                                               */
256 /*---------------------------------------------------------------------------*/
257 static void
258 gl_cairo_markup_line_path (cairo_t                 *cr,
259                            const lglTemplateMarkup *markup)
260 {
261         gl_debug (DEBUG_PATH, "START");
262
263         cairo_move_to (cr, markup->line.x1, markup->line.y1);
264         cairo_line_to (cr, markup->line.x2, markup->line.y2);
265
266         gl_debug (DEBUG_PATH, "END");
267 }
268
269
270 /*---------------------------------------------------------------------------*/
271 /* PRIVATE.  Draw circle markup.                                             */
272 /*---------------------------------------------------------------------------*/
273 static void
274 gl_cairo_markup_circle_path (cairo_t                 *cr,
275                              const lglTemplateMarkup *markup)
276 {
277         gl_debug (DEBUG_PATH, "START");
278
279         cairo_arc (cr,
280                    markup->circle.x0, markup->circle.y0,
281                    markup->circle.r,
282                    0.0, 2*G_PI);
283         cairo_close_path (cr);
284
285         gl_debug (DEBUG_PATH, "END");
286 }
287
288
289 /*---------------------------------------------------------------------------*/
290 /* PRIVATE.  Draw rect markup.                                               */
291 /*---------------------------------------------------------------------------*/
292 static void
293 gl_cairo_markup_rect_path (cairo_t                 *cr,
294                            const lglTemplateMarkup *markup)
295 {
296         gdouble x1 = markup->rect.x1;
297         gdouble y1 = markup->rect.y1;
298         gdouble w  = markup->rect.w;
299         gdouble h  = markup->rect.h;
300         gdouble r  = markup->rect.r;
301
302         gl_debug (DEBUG_PATH, "START");
303
304         if ( r == 0.0 )
305         {
306                 cairo_rectangle (cr, x1, y1, w, h);
307         }
308         else
309         {
310                 cairo_new_path (cr);
311                 cairo_arc_negative (cr, x1+r,   y1+r,   r, 3*G_PI/2, G_PI);
312                 cairo_arc_negative (cr, x1+r,   y1+h-r, r, G_PI,     G_PI/2);
313                 cairo_arc_negative (cr, x1+w-r, y1+h-r, r, G_PI/2,   0.);
314                 cairo_arc_negative (cr, x1+w-r, y1+r,   r, 2*G_PI,   3*G_PI/2);
315                 cairo_close_path (cr);
316         }
317
318         gl_debug (DEBUG_PATH, "END");
319 }
320
321
322
323 /*
324  * Local Variables:       -- emacs
325  * mode: C                -- emacs
326  * c-basic-offset: 8      -- emacs
327  * tab-width: 8           -- emacs
328  * indent-tabs-mode: nil  -- emacs
329  * End:                   -- emacs
330  */