]> git.sur5r.net Git - glabels/commitdiff
Added support for Business Card CD Labels (Clipped circular shape).
authorJim Evins <evins@snaught.com>
Thu, 2 Jan 2003 00:26:00 +0000 (00:26 +0000)
committerJim Evins <evins@snaught.com>
Thu, 2 Jan 2003 00:26:00 +0000 (00:26 +0000)
Fixed artifact hack in wdgt-rotate-label -- made sure the scroll region was
as large as the canvas, so that the label was not shoved into the upper left corner of the canvas.

git-svn-id: https://glabels.svn.sourceforge.net/svnroot/glabels/trunk@233 f5e0f49d-192f-0410-a22d-a8d8700d0965

glabels2/src/label.c
glabels2/src/print.c
glabels2/src/template.c
glabels2/src/template.h
glabels2/src/view.c
glabels2/src/wdgt-mini-preview.c
glabels2/src/wdgt-rotate-label.c

index c0e93baaba2aa38935c90474ab4b2caa80f761ef..f4db0f4bb470999a4b8366b990197d9cc2b2d0d8 100644 (file)
@@ -467,32 +467,11 @@ gl_label_get_size (glLabel *label,
                return;
        }
 
-        switch (template->label.style) {
-
-        case GL_TEMPLATE_STYLE_RECT:
-                if (!label->private->rotate_flag) {
-                        *w = template->label.rect.w;
-                        *h = template->label.rect.h;
-                } else {
-                        *w = template->label.rect.h;
-                        *h = template->label.rect.w;
-                }
-                break;
-
-        case GL_TEMPLATE_STYLE_ROUND:
-                *w = *h = 2.0 * template->label.round.r;
-                break;
-
-        case GL_TEMPLATE_STYLE_CD:
-                *w = *h = 2.0 * template->label.cd.r1;
-                break;
-
-        default:
-                g_warning ("Unknown template label style %d",
-                          template->label.style);
-               *w = *h = 0;
-               break;
-        }
+       if (!label->private->rotate_flag) {
+               gl_template_get_label_size (template, w, h);
+       } else {
+               gl_template_get_label_size (template, h, w);
+       }
 
        gl_debug (DEBUG_LABEL, "END");
 }
index 893ab3bc74fd729984d9d9723bb9ad548fb2d626..305982ee948accae626f1f146d07797d3c7f1d6b 100644 (file)
@@ -44,6 +44,9 @@
 
 #define GL_PRINT_DEFAULT_PAPER "US Letter"
 
+#define ARC_FINE   2  /* Resolution in degrees of large arcs */
+#define ARC_COURSE 5  /* Resolution in degrees of small arcs */
+
 /*=========================================================================*/
 /* Private types.                                                          */
 /*=========================================================================*/
@@ -146,6 +149,14 @@ static void       create_rounded_rectangle_path (GnomePrintContext *pc,
                                                 gdouble            w,
                                                 gdouble            h,
                                                 gdouble            r);
+
+static void       create_clipped_circle_path    (GnomePrintContext *pc,
+                                                gdouble            x0,
+                                                gdouble            y0,
+                                                gdouble            w,
+                                                gdouble            h,
+                                                gdouble            r);
+
 \f
 /*****************************************************************************/
 /* Simple (no merge data) print command.                                     */
@@ -1002,13 +1013,24 @@ draw_outline (PrintInfo *pi,
                break;
 
        case GL_TEMPLATE_STYLE_CD:
-               /* CD style, round label w/ concentric round hole */
-               r1 = template->label.cd.r1;
-               r2 = template->label.cd.r2;
-               create_ellipse_path (pi->pc, r1, r1, r1, r1);
-               gnome_print_stroke (pi->pc);
-               create_ellipse_path (pi->pc, r1, r1, r2, r2);
-               gnome_print_stroke (pi->pc);
+               if ((template->label.cd.h == 0) && (template->label.cd.w == 0)) {
+                       /* CD style, round label w/ concentric round hole */
+                       r1 = template->label.cd.r1;
+                       r2 = template->label.cd.r2;
+                       create_ellipse_path (pi->pc, r1, r1, r1, r1);
+                       gnome_print_stroke (pi->pc);
+                       create_ellipse_path (pi->pc, r1, r1, r2, r2);
+                       gnome_print_stroke (pi->pc);
+               } else {
+                       /* Business Card CD style, clipped round label w/ hole */
+                       gl_label_get_size (label, &w, &h);
+                       r1 = template->label.cd.r1;
+                       r2 = template->label.cd.r2;
+                       create_clipped_circle_path (pi->pc, w/2, h/2, w, h, r1);
+                       gnome_print_stroke (pi->pc);
+                       create_ellipse_path (pi->pc, w/2, h/2, r2, r2);
+                       gnome_print_stroke (pi->pc);
+               }
                break;
 
        default:
@@ -1059,9 +1081,18 @@ clip_to_outline (PrintInfo *pi,
                break;
 
        case GL_TEMPLATE_STYLE_CD:
-               r1 = template->label.cd.r1;
-               create_ellipse_path (pi->pc, r1, r1, r1, r1);
-               gnome_print_clip (pi->pc);
+               if ((template->label.cd.h == 0) && (template->label.cd.w == 0)) {
+                       /* CD style, round label w/ concentric round hole */
+                       r1 = template->label.cd.r1;
+                       create_ellipse_path (pi->pc, r1, r1, r1, r1);
+                       gnome_print_clip (pi->pc);
+               } else {
+                       /* Business Card CD style, clipped round label w/ hole */
+                       gl_label_get_size (label, &w, &h);
+                       r1 = template->label.cd.r1;
+                       create_clipped_circle_path (pi->pc, w/2, h/2, w, h, r1);
+                       gnome_print_clip (pi->pc);
+               }
                break;
 
        default:
@@ -1111,7 +1142,7 @@ create_ellipse_path (GnomePrintContext *pc,
 
        gnome_print_newpath (pc);
        gnome_print_moveto (pc, x0 + rx, y0);
-       for (i_theta = 2; i_theta <= 360; i_theta += 2) {
+       for (i_theta = ARC_FINE; i_theta <= 360; i_theta += ARC_FINE) {
                x = x0 + rx * cos (i_theta * G_PI / 180.0);
                y = y0 + ry * sin (i_theta * G_PI / 180.0);
                gnome_print_lineto (pc, x, y);
@@ -1137,22 +1168,22 @@ create_rounded_rectangle_path (GnomePrintContext *pc,
        gnome_print_newpath (pc);
 
        gnome_print_moveto (pc, x0 + r, y0);
-       for (i_theta = 5; i_theta <= 90; i_theta += 5) {
+       for (i_theta = ARC_COURSE; i_theta <= 90; i_theta += ARC_COURSE) {
                x = x0 + r - r * sin (i_theta * G_PI / 180.0);
                y = y0 + r - r * cos (i_theta * G_PI / 180.0);
                gnome_print_lineto (pc, x, y);
        }
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                x = x0 + r - r * cos (i_theta * G_PI / 180.0);
                y = y0 + (h - r) + r * sin (i_theta * G_PI / 180.0);
                gnome_print_lineto (pc, x, y);
        }
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                x = x0 + (w - r) + r * sin (i_theta * G_PI / 180.0);
                y = y0 + (h - r) + r * cos (i_theta * G_PI / 180.0);
                gnome_print_lineto (pc, x, y);
        }
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                x = x0 + (w - r) + r * cos (i_theta * G_PI / 180.0);
                y = y0 + r - r * sin (i_theta * G_PI / 180.0);
                gnome_print_lineto (pc, x, y);
@@ -1163,3 +1194,96 @@ create_rounded_rectangle_path (GnomePrintContext *pc,
 
        gl_debug (DEBUG_PRINT, "END");
 }
+
+static void
+create_clipped_circle_path (GnomePrintContext *pc,
+                           gdouble            x0,
+                           gdouble            y0,
+                           gdouble            w,
+                           gdouble            h,
+                           gdouble            r)
+{
+       gdouble x, y;
+       gdouble theta1, theta2;
+       gint    i_theta;
+
+       gl_debug (DEBUG_PRINT, "START");
+
+       theta1 = (180.0/G_PI) * acos (w / (2.0*r));
+       theta2 = (180.0/G_PI) * asin (h / (2.0*r));
+
+       gnome_print_newpath (pc);
+
+       x = x0 + r * cos (theta1 * G_PI / 180.0);
+       y = y0 + r * sin (theta1 * G_PI / 180.0);
+       gnome_print_moveto (pc, x, y);
+
+       for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
+               x = x0 + r * cos (i_theta * G_PI / 180.0);
+               y = y0 + r * sin (i_theta * G_PI / 180.0);
+               gnome_print_lineto (pc, x, y);
+       }
+
+       x = x0 + r * cos (theta2 * G_PI / 180.0);
+       y = y0 + r * sin (theta2 * G_PI / 180.0);
+       gnome_print_lineto (pc, x, y);
+
+       if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
+               x = x0 + r * cos ((180-theta2) * G_PI / 180.0);
+               y = y0 + r * sin ((180-theta2) * G_PI / 180.0);
+               gnome_print_lineto (pc, x, y);
+       }
+
+       for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
+               x = x0 + r * cos (i_theta * G_PI / 180.0);
+               y = y0 + r * sin (i_theta * G_PI / 180.0);
+               gnome_print_lineto (pc, x, y);
+       }
+
+       x = x0 + r * cos ((180-theta1) * G_PI / 180.0);
+       y = y0 + r * sin ((180-theta1) * G_PI / 180.0);
+       gnome_print_lineto (pc, x, y);
+
+       if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
+               x = x0 + r * cos ((180+theta1) * G_PI / 180.0);
+               y = y0 + r * sin ((180+theta1) * G_PI / 180.0);
+               gnome_print_lineto (pc, x, y);
+       }
+
+       for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
+               x = x0 + r * cos (i_theta * G_PI / 180.0);
+               y = y0 + r * sin (i_theta * G_PI / 180.0);
+               gnome_print_lineto (pc, x, y);
+       }
+
+       x = x0 + r * cos ((180+theta2) * G_PI / 180.0);
+       y = y0 + r * sin ((180+theta2) * G_PI / 180.0);
+       gnome_print_lineto (pc, x, y);
+
+       if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
+               x = x0 + r * cos ((360-theta2) * G_PI / 180.0);
+               y = y0 + r * sin ((360-theta2) * G_PI / 180.0);
+               gnome_print_lineto (pc, x, y);
+       }
+
+       for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
+               x = x0 + r * cos (i_theta * G_PI / 180.0);
+               y = y0 + r * sin (i_theta * G_PI / 180.0);
+               gnome_print_lineto (pc, x, y);
+       }
+
+       if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
+               x = x0 + r * cos ((360-theta1) * G_PI / 180.0);
+               y = y0 + r * sin ((360-theta1) * G_PI / 180.0);
+               gnome_print_lineto (pc, x, y);
+       }
+
+       x = x0 + r * cos (theta1 * G_PI / 180.0);
+       y = y0 + r * sin (theta1 * G_PI / 180.0);
+       gnome_print_lineto (pc, x, y);
+
+       gnome_print_closepath (pc);
+
+       gl_debug (DEBUG_PRINT, "END");
+}
+
index 537ce648220ee36f94d28f99c8d7908b3be9587d..29045b1a977d1c2aac7d793092b3851d4f3a4e75 100644 (file)
@@ -589,8 +589,9 @@ static void
 xml_parse_label (xmlNodePtr label_node,
                 glTemplate * template)
 {
-       xmlNodePtr node;
-       gchar *style;
+       xmlNodePtr  node;
+       gchar      *style;
+       gchar      *string;
 
        gl_debug (DEBUG_TEMPLATE, "START");
 
@@ -605,6 +606,7 @@ xml_parse_label (xmlNodePtr label_node,
                template->label.style = GL_TEMPLATE_STYLE_RECT;
                g_warning ("Unknown label style in template");
        }
+       g_free (style);
 
        switch (template->label.style) {
        case GL_TEMPLATE_STYLE_RECT:
@@ -624,6 +626,20 @@ xml_parse_label (xmlNodePtr label_node,
                    g_strtod (xmlGetProp (label_node, "radius"), NULL);
                template->label.cd.r2 =
                    g_strtod (xmlGetProp (label_node, "hole"), NULL);
+               string = xmlGetProp (label_node, "width");
+               if (string != NULL) {
+                       template->label.cd.w = g_strtod (string, NULL);
+                       g_free (string);
+               } else {
+                       template->label.cd.w = 0.0;
+               }
+               string = xmlGetProp (label_node, "height");
+               if (string != NULL) {
+                       template->label.cd.h = g_strtod (string, NULL);
+                       g_free (string);
+               } else {
+                       template->label.cd.h = 0.0;
+               }
                break;
        default:
                break;
@@ -807,6 +823,16 @@ xml_add_label (const glTemplate *template,
                string = g_strdup_printf ("%g", template->label.cd.r2);
                xmlSetProp (node, "hole", string);
                g_free (string);
+               if (template->label.cd.h != 0.0) {
+                       string = g_strdup_printf ("%g", template->label.cd.h);
+                       xmlSetProp (node, "width", string);
+                       g_free (string);
+               }
+               if (template->label.cd.w != 0.0) {
+                       string = g_strdup_printf ("%g", template->label.cd.w);
+                       xmlSetProp (node, "height", string);
+                       g_free (string);
+               }
                break;
        default:
                g_warning ("Unknown label style");
@@ -1033,8 +1059,16 @@ gl_template_get_label_size (const glTemplate *template,
                *h = 2.0 * template->label.round.r;
                break;
        case GL_TEMPLATE_STYLE_CD:
-               *w = 2.0 * template->label.cd.r1;
-               *h = 2.0 * template->label.cd.r1;
+               if (template->label.cd.w == 0.0) {
+                       *w = 2.0 * template->label.cd.r1;
+               } else {
+                       *w = template->label.cd.w;
+               }
+               if (template->label.cd.h == 0.0) {
+                       *h = 2.0 * template->label.cd.r1;
+               } else {
+                       *h = template->label.cd.h;
+               }
                break;
        default:
                *w = 0.0;
index da3707165117fbf39b058960b87211c201fcb19d..6006ea831b26e3c7518cbed400e934d29ad3686a 100644 (file)
@@ -59,7 +59,7 @@ typedef struct {
 typedef struct {
        glTemplateLabelParent parent;
 
-       gdouble               r1, r2;   /* Dimensions */
+       gdouble               r1, r2, w, h; /* Dimensions, w&h are for business card CDs */
 } glTemplateLabelCD;
 
 typedef union {
index 31ba4f15c5f441173be2817ccac54511a158b0a8..f502a01905cdb89fd93f6cc996a0832c082a0877 100644 (file)
@@ -57,6 +57,9 @@
 #define SEL_LINE_COLOR  GL_COLOR_A (0, 0, 255, 128)
 #define SEL_FILL_COLOR  GL_COLOR_A (192, 192, 255, 128)
 
+#define ARC_FINE         2 /* Resolution in degrees of large arcs */
+#define ARC_COURSE       5 /* Resolution in degrees of small arcs */
+
 /*==========================================================================*/
 /* Private types.                                                           */
 /*==========================================================================*/
@@ -115,6 +118,7 @@ static void       draw_bg_fg_rect                 (glView *view);
 static void       draw_bg_fg_rounded_rect         (glView *view);
 static void       draw_bg_fg_round                (glView *view);
 static void       draw_bg_fg_cd                   (glView *view);
+static void       draw_bg_fg_cd_bc                (glView *view);
 
 static void       draw_grid_layer                 (glView *view);
 
@@ -130,6 +134,8 @@ static void       draw_markup_margin_round        (glView *view,
                                                   glTemplateMarkupMargin *margin);
 static void       draw_markup_margin_cd           (glView *view,
                                                   glTemplateMarkupMargin *margin);
+static void       draw_markup_margin_cd_bc        (glView *view,
+                                                  glTemplateMarkupMargin *margin);
 
 static void       draw_markup_line                (glView *view,
                                                   glTemplateMarkupLine   *line);
@@ -593,7 +599,11 @@ draw_bg_fg_layers (glView *view)
                break;
 
        case GL_TEMPLATE_STYLE_CD:
-               draw_bg_fg_cd (view);
+               if ((template->label.cd.w == 0.0) && (template->label.cd.h == 0.0) ) {
+                       draw_bg_fg_cd (view);
+               } else {
+                       draw_bg_fg_cd_bc (view);
+               }
                break;
 
        default:
@@ -667,27 +677,27 @@ draw_bg_fg_rounded_rect (glView *view)
        template = gl_label_get_template (label);
        r = template->label.rect.r;
 
-       points = gnome_canvas_points_new (4 * (1 + 90 / 5));
+       points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
        i_coords = 0;
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                points->coords[i_coords++] =
                    r - r * sin (i_theta * G_PI / 180.0);
                points->coords[i_coords++] =
                    r - r * cos (i_theta * G_PI / 180.0);
        }
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                points->coords[i_coords++] =
                    r - r * cos (i_theta * G_PI / 180.0);
                points->coords[i_coords++] =
                    (h - r) + r * sin (i_theta * G_PI / 180.0);
        }
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                points->coords[i_coords++] =
                    (w - r) + r * sin (i_theta * G_PI / 180.0);
                points->coords[i_coords++] =
                    (h - r) + r * cos (i_theta * G_PI / 180.0);
        }
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                points->coords[i_coords++] =
                    (w - r) + r * cos (i_theta * G_PI / 180.0);
                points->coords[i_coords++] =
@@ -824,6 +834,135 @@ draw_bg_fg_cd (glView *view)
        gl_debug (DEBUG_VIEW, "END");
 }
 
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw Business Card CD style background, CD w/ chopped ends.     */
+/*---------------------------------------------------------------------------*/
+static void
+draw_bg_fg_cd_bc (glView *view)
+{
+       glLabel           *label = view->label;
+       glTemplate        *template;
+       GnomeCanvasPoints *points;
+       gint               i_coords, i_theta;
+       gdouble            theta1, theta2;
+       gdouble            x0, y0, w, h, r1, r2;
+       GnomeCanvasItem   *item;
+
+       gl_debug (DEBUG_VIEW, "START");
+
+       g_return_if_fail (GL_IS_VIEW (view));
+       g_return_if_fail (label != NULL);
+
+       template = gl_label_get_template (label);
+       gl_label_get_size (label, &w, &h);
+       x0 = w/2.0;
+       y0 = h/2.0;
+
+       r1 = template->label.cd.r1;
+       r2 = template->label.cd.r2;
+
+       theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
+       theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
+
+       points = gnome_canvas_points_new (360/ARC_FINE + 1);
+       i_coords = 0;
+
+       points->coords[i_coords++] = x0 + r1 * cos (theta1 * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r1 * sin (theta1 * G_PI / 180.0);
+
+       for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
+               points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = x0 + r1 * cos (theta2 * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r1 * sin (theta2 * G_PI / 180.0);
+
+
+       if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r1 * cos ((180-theta2) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r1 * sin ((180-theta2) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
+               points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = x0 + r1 * cos ((180-theta1) * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r1 * sin ((180-theta1) * G_PI / 180.0);
+
+       if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r1 * cos ((180+theta1) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r1 * sin ((180+theta1) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
+               points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = x0 + r1 * cos ((180+theta2) * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r1 * sin ((180+theta2) * G_PI / 180.0);
+
+       if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r1 * cos ((360-theta2) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r1 * sin ((360-theta2) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
+               points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
+       }
+
+       if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r1 * cos ((360-theta1) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r1 * sin ((360-theta1) * G_PI / 180.0);
+       }
+
+       points->num_points = i_coords / 2;
+
+       /* Background */
+       /* outer circle */
+       item = gnome_canvas_item_new (view->bg_group,
+                                     gnome_canvas_polygon_get_type (),
+                                     "points", points,
+                                     "fill_color_rgba", PAPER_COLOR,
+                                     NULL);
+       /* hole */
+       item = gnome_canvas_item_new (view->bg_group,
+                                     gnome_canvas_ellipse_get_type (),
+                                     "x1", x0 - r2,
+                                     "y1", y0 - r2,
+                                     "x2", x0 + r2,
+                                     "y2", y0 + r2,
+                                     "fill_color_rgba", GRID_COLOR,
+                                     NULL);
+
+       /* Foreground */
+       /* outer circle */
+       item = gnome_canvas_item_new (view->fg_group,
+                                     gnome_canvas_polygon_get_type (),
+                                     "points", points,
+                                     "width_pixels", 2,
+                                     "outline_color_rgba", OUTLINE_COLOR,
+                                     NULL);
+       /* hole */
+       item = gnome_canvas_item_new (view->fg_group,
+                                     gnome_canvas_ellipse_get_type (),
+                                     "x1", x0 - r2,
+                                     "y1", y0 - r2,
+                                     "x2", x0 + r2,
+                                     "y2", y0 + r2,
+                                     "width_pixels", 2,
+                                     "outline_color_rgba", OUTLINE_COLOR,
+                                     NULL);
+
+       gnome_canvas_points_free (points);
+
+       gl_debug (DEBUG_VIEW, "END");
+}
+
 /*---------------------------------------------------------------------------*/
 /* PRIVATE.  Draw grid lines.                                                */
 /*---------------------------------------------------------------------------*/
@@ -970,7 +1109,11 @@ draw_markup_margin (glView                 *view,
                break;
 
        case GL_TEMPLATE_STYLE_CD:
-               draw_markup_margin_cd (view, margin);
+               if ((template->label.cd.w == 0.0) && (template->label.cd.h == 0.0) ) {
+                       draw_markup_margin_cd (view, margin);
+               } else {
+                       draw_markup_margin_cd_bc (view, margin);
+               }
                break;
 
        default:
@@ -1043,27 +1186,27 @@ draw_markup_margin_rounded_rect (glView                 *view,
        h = h - 2 * m;
 
        /* rectangle with rounded corners */
-       points = gnome_canvas_points_new (4 * (1 + 90 / 5));
+       points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
        i_coords = 0;
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                points->coords[i_coords++] =
                        m + r - r * sin (i_theta * G_PI / 180.0);
                points->coords[i_coords++] =
                        m + r - r * cos (i_theta * G_PI / 180.0);
        }
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                points->coords[i_coords++] =
                        m + r - r * cos (i_theta * G_PI / 180.0);
                points->coords[i_coords++] =
                        m + (h - r) + r * sin (i_theta * G_PI / 180.0);
        }
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                points->coords[i_coords++] =
                        m + (w - r) + r * sin (i_theta * G_PI / 180.0);
                points->coords[i_coords++] =
                        m + (h - r) + r * cos (i_theta * G_PI / 180.0);
        }
-       for (i_theta = 0; i_theta <= 90; i_theta += 5) {
+       for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
                points->coords[i_coords++] =
                        m + (w - r) + r * cos (i_theta * G_PI / 180.0);
                points->coords[i_coords++] =
@@ -1163,6 +1306,122 @@ draw_markup_margin_cd (glView                 *view,
        gl_debug (DEBUG_VIEW, "END");
 }
 
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw Business Card CD margins.                                  */
+/*---------------------------------------------------------------------------*/
+static void
+draw_markup_margin_cd_bc (glView                 *view,
+                         glTemplateMarkupMargin *margin)
+{
+       glLabel           *label = view->label;
+       glTemplate        *template;
+       gdouble            m, r1, r2;
+       GnomeCanvasPoints *points;
+       gint               i_coords, i_theta;
+       gdouble            theta1, theta2;
+       gdouble            x0, y0, w, h, r;
+       GnomeCanvasItem   *item;
+
+       gl_debug (DEBUG_VIEW, "START");
+
+       g_return_if_fail (GL_IS_VIEW (view));
+       g_return_if_fail (label != NULL);
+
+       template = gl_label_get_template (label);
+       gl_label_get_size (label, &w, &h);
+       x0 = w/2.0;
+       y0 = h/2.0;
+
+       r1 = template->label.cd.r1;
+       r2 = template->label.cd.r2;
+       m  = margin->size;
+
+       /* outer margin */
+       r = r1 - m;
+       theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
+       theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
+
+       points = gnome_canvas_points_new (360/ARC_FINE + 1);
+       i_coords = 0;
+
+       points->coords[i_coords++] = x0 + r * cos (theta1 * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r * sin (theta1 * G_PI / 180.0);
+
+       for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
+               points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = x0 + r * cos (theta2 * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r * sin (theta2 * G_PI / 180.0);
+
+
+       if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r * cos ((180-theta2) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin ((180-theta2) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
+               points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = x0 + r * cos ((180-theta1) * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r * sin ((180-theta1) * G_PI / 180.0);
+
+       if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r * cos ((180+theta1) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin ((180+theta1) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
+               points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = x0 + r * cos ((180+theta2) * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r * sin ((180+theta2) * G_PI / 180.0);
+
+       if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r * cos ((360-theta2) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin ((360-theta2) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
+               points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
+       }
+
+       if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r * cos ((360-theta1) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin ((360-theta1) * G_PI / 180.0);
+       }
+
+       points->num_points = i_coords / 2;
+
+       item = gnome_canvas_item_new (view->markup_group,
+                                     gnome_canvas_polygon_get_type (),
+                                     "points", points,
+                                     "width_pixels", 1,
+                                     "outline_color_rgba", MARKUP_COLOR,
+                                     NULL);
+
+       gnome_canvas_points_free (points);
+
+       /* inner margin */
+       item = gnome_canvas_item_new (view->markup_group,
+                                     gnome_canvas_ellipse_get_type (),
+                                     "x1", x0 - r2 - m,
+                                     "y1", y0 - r2 - m,
+                                     "x2", x0 + r2 + m,
+                                     "y2", y0 + r2 + m,
+                                     "width_pixels", 1,
+                                     "outline_color_rgba", MARKUP_COLOR,
+                                     NULL);
+
+       gl_debug (DEBUG_VIEW, "END");
+}
+
 /*---------------------------------------------------------------------------*/
 /* PRIVATE.  Draw line markup.                                               */
 /*---------------------------------------------------------------------------*/
index ba8c5d342b264d9bc00e3991f37e0893713172d7..900ad50dbdf7d0bfe69f231b70764c19c396181a 100644 (file)
@@ -22,7 +22,8 @@
 
 #include <config.h>
 
-#include "libgnomeprint/gnome-print-paper.h"
+#include <math.h>
+#include <libgnomeprint/gnome-print-paper.h>
 
 #include "wdgt-mini-preview.h"
 #include "marshal.h"
@@ -35,6 +36,8 @@
 #define SHADOW_Y_OFFSET 3
 #define SHADOW_COLOR GL_COLOR_A (33, 33, 33, 192)
 
+#define RES 5 /* Resolution in degrees for Business Card CD outlines */
+
 /*===========================================*/
 /* Private types                             */
 /*===========================================*/
@@ -72,6 +75,13 @@ static void mini_outline_list_free             (GList ** list);
 static gint canvas_event_cb                    (GnomeCanvas * canvas,
                                                GdkEvent * event,
                                                gpointer data);
+
+static GnomeCanvasItem *cdbc_item              (GnomeCanvasGroup *group,
+                                               gdouble           x1,
+                                               gdouble           y1,
+                                               glTemplate       *template);
+
+
 \f
 /****************************************************************************/
 /* Boilerplate Object stuff.                                                */
@@ -366,7 +376,6 @@ mini_outline_list_new (GnomeCanvas *canvas,
                                                      NULL);
                        break;
                case GL_TEMPLATE_STYLE_ROUND:
-               case GL_TEMPLATE_STYLE_CD:
                        item = gnome_canvas_item_new (group,
                                                      gnome_canvas_ellipse_get_type(),
                                                      "x1", x1,
@@ -378,6 +387,22 @@ mini_outline_list_new (GnomeCanvas *canvas,
                                                      "fill_color", "white",
                                                      NULL);
                        break;
+               case GL_TEMPLATE_STYLE_CD:
+                       if ( w == h ) {
+                               item = gnome_canvas_item_new (group,
+                                                             gnome_canvas_ellipse_get_type(),
+                                                             "x1", x1,
+                                                             "y1", y1,
+                                                             "x2", x2,
+                                                             "y2", y2,
+                                                             "width_pixels", 1,
+                                                             "outline_color", "black",
+                                                             "fill_color", "white",
+                                                             NULL);
+                       } else {
+                               item = cdbc_item (group, x1, y1, template);
+                       }
+                       break;
                default:
                        g_warning ("Unknown label style");
                        return list;
@@ -562,3 +587,98 @@ gl_wdgt_mini_preview_highlight_range (glWdgtMiniPreview * preview,
        gl_debug (DEBUG_MINI_PREVIEW, "END");
 }
 
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Draw CD business card item (cut-off in w and/or h).            */
+/*--------------------------------------------------------------------------*/
+static GnomeCanvasItem *
+cdbc_item (GnomeCanvasGroup *group,
+          gdouble           x1,
+          gdouble           y1,
+          glTemplate       *template)
+{
+       GnomeCanvasPoints *points;
+       gint               i_coords, i_theta;
+       gdouble            theta1, theta2;
+       gdouble            x0, y0, w, h, r;
+       GnomeCanvasItem   *item;
+
+       gl_template_get_label_size (template, &w, &h);
+       r = template->label.cd.r1;
+       x0 = x1 + (w/2.0);
+       y0 = y1 + (h/2.0);
+
+       theta1 = (180.0/G_PI) * acos (w / (2.0*r));
+       theta2 = (180.0/G_PI) * asin (h / (2.0*r));
+
+       points = gnome_canvas_points_new (360/RES + 1);
+       i_coords = 0;
+
+       points->coords[i_coords++] = x0 + r * cos (theta1 * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r * sin (theta1 * G_PI / 180.0);
+
+       for ( i_theta = theta1 + RES; i_theta < theta2; i_theta +=RES ) {
+               points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = x0 + r * cos (theta2 * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r * sin (theta2 * G_PI / 180.0);
+
+
+       if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r * cos ((180-theta2) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin ((180-theta2) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 180-theta2+RES; i_theta < (180-theta1); i_theta +=RES ) {
+               points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = x0 + r * cos ((180-theta1) * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r * sin ((180-theta1) * G_PI / 180.0);
+
+       if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r * cos ((180+theta1) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin ((180+theta1) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 180+theta1+RES; i_theta < (180+theta2); i_theta +=RES ) {
+               points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = x0 + r * cos ((180+theta2) * G_PI / 180.0);
+       points->coords[i_coords++] = y0 + r * sin ((180+theta2) * G_PI / 180.0);
+
+       if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r * cos ((360-theta2) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin ((360-theta2) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 360-theta2+RES; i_theta < (360-theta1); i_theta +=RES ) {
+               points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
+       }
+
+       if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = x0 + r * cos ((360-theta1) * G_PI / 180.0);
+               points->coords[i_coords++] = y0 + r * sin ((360-theta1) * G_PI / 180.0);
+       }
+
+       points->num_points = i_coords / 2;
+
+
+       item = gnome_canvas_item_new (group,
+                                     gnome_canvas_polygon_get_type (),
+                                     "points", points,
+                                     "width_pixels", 1,
+                                     "outline_color", "black",
+                                     "fill_color", "white",
+                                     NULL);
+
+       gnome_canvas_points_free (points);
+
+       return item;
+}
+
index d1a04d60d728103f575e3f6835f3f4de29d3d54c..283b2b7527a8f2e9b671470782b2c39d4f896229 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <config.h>
 
+#include <math.h>
+
 #include "wdgt-rotate-label.h"
 #include "hig.h"
 #include "template.h"
 /* Private macros and constants.                          */
 /*========================================================*/
 #define MINI_PREVIEW_MAX_PIXELS 48
+#define MINI_PREVIEW_CANVAS_PIXELS (MINI_PREVIEW_MAX_PIXELS + 8)
 
 #define LINE_COLOR             GL_COLOR(0,0,0)
 #define FILL_COLOR             GL_COLOR(255,255,255)
 #define UNSENSITIVE_LINE_COLOR GL_COLOR(0x66,0x66,0x66)
 #define UNSENSITIVE_FILL_COLOR GL_COLOR(0xCC,0xCC,0xCC)
 
+#define RES 5 /* Resolution in degrees for Business Card CD outlines */
+
 /*===========================================*/
 /* Private types                             */
 /*===========================================*/
@@ -63,20 +68,28 @@ static gint wdgt_rotate_label_signals[LAST_SIGNAL] = { 0 };
 /* Local function prototypes                 */
 /*===========================================*/
 
-static void gl_wdgt_rotate_label_class_init    (glWdgtRotateLabelClass * class);
-static void gl_wdgt_rotate_label_instance_init (glWdgtRotateLabel rotate_select);
-static void gl_wdgt_rotate_label_finalize      (GObject object);
+static void gl_wdgt_rotate_label_class_init    (glWdgtRotateLabelClass *class);
+static void gl_wdgt_rotate_label_instance_init (glWdgtRotateLabel      *rotate_select);
+static void gl_wdgt_rotate_label_finalize      (GObject                *object);
 
-static void gl_wdgt_rotate_label_construct     (glWdgtRotateLabel rotate_select);
+static void gl_wdgt_rotate_label_construct     (glWdgtRotateLabel      *rotate_select);
 
-static void entry_changed_cb                   (GtkToggleButton * toggle,
-                                               gpointer user_data);
+static void entry_changed_cb                   (GtkToggleButton *toggle,
+                                               gpointer         user_data);
 
 static GtkWidget *mini_preview_canvas_new      (void);
 
-static void mini_preview_canvas_update         (GnomeCanvas * canvas,
-                                               glTemplate * template,
-                                               gboolean rotate_flag);
+static void mini_preview_canvas_update         (GnomeCanvas      *canvas,
+                                               glTemplate       *template,
+                                               gboolean          rotate_flag);
+
+static GnomeCanvasItem *cdbc_item              (GnomeCanvasGroup *group,
+                                               gdouble           w,
+                                               gdouble           h,
+                                               gdouble           r,
+                                               guint             line_width,
+                                               guint             line_color,
+                                               guint             fill_color);
 
 /****************************************************************************/
 /* Boilerplate Object stuff.                                                */
@@ -110,7 +123,7 @@ gl_wdgt_rotate_label_get_type (void)
 }
 
 static void
-gl_wdgt_rotate_label_class_init (glWdgtRotateLabelClass * class)
+gl_wdgt_rotate_label_class_init (glWdgtRotateLabelClass *class)
 {
        GObjectClass *object_class;
 
@@ -132,7 +145,7 @@ gl_wdgt_rotate_label_class_init (glWdgtRotateLabelClass * class)
 }
 
 static void
-gl_wdgt_rotate_label_instance_init (glWdgtRotateLabel * rotate_select)
+gl_wdgt_rotate_label_instance_init (glWdgtRotateLabel *rotate_select)
 {
        rotate_select->rotate_check = NULL;
 
@@ -142,9 +155,9 @@ gl_wdgt_rotate_label_instance_init (glWdgtRotateLabel * rotate_select)
 }
 
 static void
-gl_wdgt_rotate_label_finalize (GObject * object)
+gl_wdgt_rotate_label_finalize (GObject *object)
 {
-       glWdgtRotateLabel *rotate_select;
+       glWdgtRotateLabel      *rotate_select;
        glWdgtRotateLabelClass *class;
 
        g_return_if_fail (object != NULL);
@@ -171,7 +184,7 @@ gl_wdgt_rotate_label_new (void)
 /* Construct composite widget.                                              */
 /*--------------------------------------------------------------------------*/
 static void
-gl_wdgt_rotate_label_construct (glWdgtRotateLabel * rotate_select)
+gl_wdgt_rotate_label_construct (glWdgtRotateLabel *rotate_select)
 {
        GtkWidget *whbox;
 
@@ -196,8 +209,8 @@ gl_wdgt_rotate_label_construct (glWdgtRotateLabel * rotate_select)
 /* PRIVATE.  modify widget due to change of check button                    */
 /*--------------------------------------------------------------------------*/
 static void
-entry_changed_cb (GtkToggleButton * toggle,
-                 gpointer user_data)
+entry_changed_cb (GtkToggleButton *toggle,
+                 gpointer         user_data)
 {
        glWdgtRotateLabel *rotate_select = GL_WDGT_ROTATE_LABEL (user_data);
 
@@ -230,8 +243,8 @@ mini_preview_canvas_new (void)
        gtk_widget_pop_colormap ();
 
        gtk_widget_set_size_request (GTK_WIDGET (wcanvas),
-                                    MINI_PREVIEW_MAX_PIXELS + 8,
-                                    MINI_PREVIEW_MAX_PIXELS + 8);
+                                    MINI_PREVIEW_CANVAS_PIXELS,
+                                    MINI_PREVIEW_CANVAS_PIXELS);
 
        gtk_object_set_data (GTK_OBJECT (wcanvas), "label_item", NULL);
 
@@ -242,34 +255,30 @@ mini_preview_canvas_new (void)
 /* PRIVATE.  Update mini-preview canvas from new template.                  */
 /*--------------------------------------------------------------------------*/
 static void
-mini_preview_canvas_update (GnomeCanvas * canvas,
-                           glTemplate template,
-                           gboolean rotate_flag)
+mini_preview_canvas_update (GnomeCanvas *canvas,
+                           glTemplate  *template,
+                           gboolean     rotate_flag)
 {
-       gdouble canvas_scale;
+       gdouble           canvas_scale;
        GnomeCanvasGroup *group = NULL;
-       GnomeCanvasItem *label_item = NULL;
-       gdouble m, raw_w, raw_h, w, h;
-       guint line_color, fill_color;
+       GnomeCanvasItem  *label_item = NULL;
+       gdouble           m, m_canvas, w, h;
+       guint             line_color, fill_color;
 
        /* Fetch our data from canvas */
        label_item = g_object_get_data (G_OBJECT (canvas), "label_item");
 
-       gl_template_get_label_size (template, &raw_w, &raw_h);
-       m = MAX (raw_w, raw_h);
-       canvas_scale = (MINI_PREVIEW_MAX_PIXELS) / m;
-
-       /* FIXME: Stupid hack to eliminate canvas artifacts. */
-       if (rotate_flag) {
-               canvas_scale *= 1.02;
-       }
+       gl_template_get_label_size (template, &w, &h);
+       m = MAX (w, h);
+       canvas_scale = MINI_PREVIEW_MAX_PIXELS / m;
+       m_canvas = MINI_PREVIEW_CANVAS_PIXELS / canvas_scale;
 
        /* scale and size canvas */
        gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (canvas), canvas_scale);
        group = gnome_canvas_root (GNOME_CANVAS (canvas));
        gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas),
-                                       -m / 2.0, -m / 2.0,
-                                       +m / 2.0, +m / 2.0);
+                                       -m_canvas / 2.0, -m_canvas / 2.0,
+                                       +m_canvas / 2.0, +m_canvas / 2.0);
 
        /* remove old label outline */
        if (label_item != NULL) {
@@ -277,7 +286,7 @@ mini_preview_canvas_update (GnomeCanvas * canvas,
        }
 
        /* Adjust sensitivity (should the canvas be grayed?) */
-       if (raw_w != raw_h) {
+       if (w != h) {
                line_color = LINE_COLOR;
                fill_color = FILL_COLOR;
        } else {
@@ -286,13 +295,6 @@ mini_preview_canvas_update (GnomeCanvas * canvas,
        }
 
        /* draw mini label outline */
-       if (!rotate_flag) {
-               w = raw_w;
-               h = raw_h;
-       } else {
-               w = raw_h;
-               h = raw_w;
-       }
        switch (template->label.style) {
        case GL_TEMPLATE_STYLE_RECT:
                label_item = gnome_canvas_item_new (group,
@@ -307,23 +309,47 @@ mini_preview_canvas_update (GnomeCanvas * canvas,
                                                    NULL);
                break;
        case GL_TEMPLATE_STYLE_ROUND:
-       case GL_TEMPLATE_STYLE_CD:
                label_item = gnome_canvas_item_new (group,
                                                    gnome_canvas_ellipse_get_type(),
                                                    "x1", -w / 2.0,
                                                    "y1", -h / 2.0,
                                                    "x2", +w / 2.0,
                                                    "y2", +h / 2.0,
-                                                   "width_pixels", 2,
+                                                   "width_pixels", 1,
                                                    "outline_color_rgba", line_color,
                                                    "fill_color_rgba", fill_color,
                                                    NULL);
                break;
+       case GL_TEMPLATE_STYLE_CD:
+               if ( w == h ) {
+                       label_item = gnome_canvas_item_new (group,
+                                                           gnome_canvas_ellipse_get_type(),
+                                                           "x1", -w / 2.0,
+                                                           "y1", -h / 2.0,
+                                                           "x2", +w / 2.0,
+                                                           "y2", +h / 2.0,
+                                                           "width_pixels", 1,
+                                                           "outline_color_rgba", line_color,
+                                                           "fill_color_rgba", fill_color,
+                                                           NULL);
+               } else {
+                       label_item = cdbc_item (group,
+                                               w, h, template->label.cd.r1,
+                                               1, line_color, fill_color);
+               }
+               break;
        default:
                g_warning ("Unknown label style");
                break;
        }
 
+       if (rotate_flag) {
+               gdouble affine[6];
+
+               art_affine_rotate (affine, 90);
+               gnome_canvas_item_affine_absolute (label_item, affine);
+       }
+
        gtk_object_set_data (GTK_OBJECT (canvas), "label_item", label_item);
 
 }
@@ -332,7 +358,7 @@ mini_preview_canvas_update (GnomeCanvas * canvas,
 /* query state of widget.                                                   */
 /****************************************************************************/
 gboolean
-gl_wdgt_rotate_label_get_state (glWdgtRotateLabel * rotate_select)
+gl_wdgt_rotate_label_get_state (glWdgtRotateLabel *rotate_select)
 {
        return
            gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
@@ -343,7 +369,7 @@ gl_wdgt_rotate_label_get_state (glWdgtRotateLabel * rotate_select)
 /* set state of widget.                                                     */
 /****************************************************************************/
 void
-gl_wdgt_rotate_label_set_state (glWdgtRotateLabel * rotate_select,
+gl_wdgt_rotate_label_set_state (glWdgtRotateLabel *rotate_select,
                                gboolean state)
 {
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
@@ -354,11 +380,11 @@ gl_wdgt_rotate_label_set_state (glWdgtRotateLabel * rotate_select,
 /* set template for widget.                                                 */
 /****************************************************************************/
 void
-gl_wdgt_rotate_label_set_template_name (glWdgtRotateLabel * rotate_select,
-                                       gchar name)
+gl_wdgt_rotate_label_set_template_name (glWdgtRotateLabel *rotate_select,
+                                       gchar             *name)
 {
        glTemplate *template;
-       gdouble raw_w, raw_h;
+       gdouble     raw_w, raw_h;
 
        template = gl_template_from_name (name);
        rotate_select->template = template;
@@ -372,3 +398,96 @@ gl_wdgt_rotate_label_set_template_name (glWdgtRotateLabel * rotate_select,
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
                                      (rotate_select->rotate_check), FALSE);
 }
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Draw CD business card item (cut-off in w and/or h).            */
+/*--------------------------------------------------------------------------*/
+static GnomeCanvasItem *
+cdbc_item (GnomeCanvasGroup *group,
+          gdouble           w,
+          gdouble           h,
+          gdouble           r,
+          guint             line_width,
+          guint             line_color,
+          guint             fill_color)
+{
+       GnomeCanvasPoints *points;
+       gint               i_coords, i_theta;
+       gdouble            theta1, theta2;
+       GnomeCanvasItem   *item;
+
+       theta1 = (180.0/G_PI) * acos (w / (2.0*r));
+       theta2 = (180.0/G_PI) * asin (h / (2.0*r));
+
+       points = gnome_canvas_points_new (360/RES + 1);
+       i_coords = 0;
+
+       points->coords[i_coords++] = r * cos (theta1 * G_PI / 180.0);
+       points->coords[i_coords++] = r * sin (theta1 * G_PI / 180.0);
+
+       for ( i_theta = theta1 + RES; i_theta < theta2; i_theta +=RES ) {
+               points->coords[i_coords++] = r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = r * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = r * cos (theta2 * G_PI / 180.0);
+       points->coords[i_coords++] = r * sin (theta2 * G_PI / 180.0);
+
+
+       if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = r * cos ((180-theta2) * G_PI / 180.0);
+               points->coords[i_coords++] = r * sin ((180-theta2) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 180-theta2+RES; i_theta < (180-theta1); i_theta +=RES ) {
+               points->coords[i_coords++] = r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = r * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = r * cos ((180-theta1) * G_PI / 180.0);
+       points->coords[i_coords++] = r * sin ((180-theta1) * G_PI / 180.0);
+
+       if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = r * cos ((180+theta1) * G_PI / 180.0);
+               points->coords[i_coords++] = r * sin ((180+theta1) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 180+theta1+RES; i_theta < (180+theta2); i_theta +=RES ) {
+               points->coords[i_coords++] = r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = r * sin (i_theta * G_PI / 180.0);
+       }
+
+       points->coords[i_coords++] = r * cos ((180+theta2) * G_PI / 180.0);
+       points->coords[i_coords++] = r * sin ((180+theta2) * G_PI / 180.0);
+
+       if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = r * cos ((360-theta2) * G_PI / 180.0);
+               points->coords[i_coords++] = r * sin ((360-theta2) * G_PI / 180.0);
+       }
+
+       for ( i_theta = 360-theta2+RES; i_theta < (360-theta1); i_theta +=RES ) {
+               points->coords[i_coords++] = r * cos (i_theta * G_PI / 180.0);
+               points->coords[i_coords++] = r * sin (i_theta * G_PI / 180.0);
+       }
+
+       if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
+               points->coords[i_coords++] = r * cos ((360-theta1) * G_PI / 180.0);
+               points->coords[i_coords++] = r * sin ((360-theta1) * G_PI / 180.0);
+       }
+
+       points->num_points = i_coords / 2;
+
+
+       item = gnome_canvas_item_new (group,
+                                     gnome_canvas_polygon_get_type (),
+                                     "points", points,
+                                     "width_pixels", line_width,
+                                     "outline_color_rgba", line_color,
+                                     "fill_color_rgba", fill_color,
+                                     NULL);
+
+       gnome_canvas_points_free (points);
+
+       return item;
+}
+