]> git.sur5r.net Git - glabels/blob - glabels2/src/cairo-label-path.c
2007-09-14 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / 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                                                   glTemplate             *template,
48                                                   gboolean                rotate_flag,
49                                                   gboolean                waste_flag);
50 static void gl_cairo_round_label_path            (cairo_t                *cr,
51                                                   glTemplate             *template,
52                                                   gboolean                rotate_flag,
53                                                   gboolean                waste_flag);
54 static void gl_cairo_cd_label_path               (cairo_t                *cr,
55                                                   glTemplate             *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                      glTemplate        *template,
66                      gboolean           rotate_flag,
67                      gboolean           waste_flag)
68 {
69         const glTemplateLabelType *label_type;
70
71         gl_debug (DEBUG_PATH, "START");
72
73         label_type = gl_template_get_first_label_type (template);
74
75         switch (label_type->shape) {
76
77         case GL_TEMPLATE_SHAPE_RECT:
78                 gl_cairo_rect_label_path (cr, template, rotate_flag, waste_flag);
79                 break;
80
81         case GL_TEMPLATE_SHAPE_ROUND:
82                 gl_cairo_round_label_path (cr, template, rotate_flag, waste_flag);
83                 break;
84
85         case GL_TEMPLATE_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                           glTemplate        *template,
103                           gboolean           rotate_flag,
104                           gboolean           waste_flag)
105 {
106         const glTemplateLabelType *label_type;
107         gdouble                    w, h, r;
108         gdouble                    x_waste, y_waste;
109
110         gl_debug (DEBUG_PATH, "START");
111
112         label_type = gl_template_get_first_label_type (template);
113         r = label_type->size.rect.r;
114
115         x_waste = 0.0;
116         y_waste = 0.0;
117
118         if (rotate_flag)
119         {
120                 gl_template_get_label_size (label_type, &h, &w);
121                 if (waste_flag)
122                 {
123                         x_waste = label_type->size.rect.y_waste;
124                         y_waste = label_type->size.rect.x_waste;
125                 }
126         }
127         else
128         {
129                 gl_template_get_label_size (label_type, &w, &h);
130                 if (waste_flag)
131                 {
132                         x_waste = label_type->size.rect.x_waste;
133                         y_waste = label_type->size.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                            glTemplate        *template,
161                            gboolean           rotate_flag,
162                            gboolean           waste_flag)
163 {
164         const glTemplateLabelType *label_type;
165         gdouble                    w, h;
166         gdouble                    waste;
167
168         gl_debug (DEBUG_PATH, "START");
169
170         label_type = gl_template_get_first_label_type (template);
171         
172         if (rotate_flag)
173         {
174                 gl_template_get_label_size (label_type, &h, &w);
175         }
176         else
177         {
178                 gl_template_get_label_size (label_type, &w, &h);
179         }
180
181         if (waste_flag)
182         {
183                 waste = label_type->size.round.waste;
184         }
185         else
186         {
187                 waste = 0.0;
188         }
189
190         cairo_arc (cr, w/2, h/2, w/2+waste, 0.0, 2*G_PI);
191         cairo_close_path (cr);
192
193         gl_debug (DEBUG_PATH, "END");
194 }
195
196 /*--------------------------------------------------------------------------*/
197 /* Create cd label path                                                     */
198 /*--------------------------------------------------------------------------*/
199 static void
200 gl_cairo_cd_label_path (cairo_t           *cr,
201                         glTemplate        *template,
202                         gboolean           rotate_flag,
203                         gboolean           waste_flag)
204 {
205         const glTemplateLabelType *label_type;
206         gdouble                    w, h;
207         gdouble                    xc, yc;
208         gdouble                    r1, r2;
209         gdouble                    theta1, theta2;
210         gdouble                    waste;
211
212         gl_debug (DEBUG_PATH, "START");
213
214         label_type = gl_template_get_first_label_type (template);
215
216         if (rotate_flag)
217         {
218                 gl_template_get_label_size (label_type, &h, &w);
219         }
220         else
221         {
222                 gl_template_get_label_size (label_type, &w, &h);
223         }
224
225         xc = w/2.0;
226         yc = h/2.0;
227
228         r1 = label_type->size.cd.r1;
229         r2 = label_type->size.cd.r2;
230
231         if (waste_flag)
232         {
233                 waste = label_type->size.cd.waste;
234         }
235         else
236         {
237                 waste = 0.0;
238         }
239
240         /*
241          * Outer path (may be clipped in the case of a business card type CD)
242          */
243         theta1 = acos (w / (2.0*r1));
244         theta2 = asin (h / (2.0*r1));
245
246         cairo_new_path (cr);
247         cairo_arc (cr, xc, yc, r1+waste, theta1, theta2);
248         cairo_arc (cr, xc, yc, r1+waste, G_PI-theta2, G_PI-theta1);
249         cairo_arc (cr, xc, yc, r1+waste, G_PI+theta1, G_PI+theta2);
250         cairo_arc (cr, xc, yc, r1+waste, 2*G_PI-theta2, 2*G_PI-theta1);
251         cairo_close_path (cr);
252
253
254         /*
255          * Inner path (hole)
256          */
257         cairo_new_sub_path (cr);
258         cairo_arc (cr, xc, yc, r2-waste, 0.0, 2*G_PI);
259         cairo_close_path (cr);
260
261         gl_debug (DEBUG_PATH, "END");
262 }
263