]> git.sur5r.net Git - glabels/blobdiff - src/cairo-markup-path.c
Organized master branch to be top-level directory for glabels, instead of
[glabels] / src / cairo-markup-path.c
diff --git a/src/cairo-markup-path.c b/src/cairo-markup-path.c
new file mode 100644 (file)
index 0000000..7a8bab3
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ *  cairo-markup-path.c
+ *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of gLabels.
+ *
+ *  gLabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  gLabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "cairo-markup-path.h"
+
+#include <math.h>
+
+#include "debug.h"
+
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+static void       gl_cairo_markup_margin_path         (cairo_t                 *cr,
+                                                       const lglTemplateMarkup *markup,
+                                                       glLabel                 *label);
+
+static void       gl_cairo_markup_margin_rect_path    (cairo_t                 *cr,
+                                                       const lglTemplateMarkup *markup,
+                                                       glLabel                 *label);
+
+static void       gl_cairo_markup_margin_round_path   (cairo_t                 *cr,
+                                                       const lglTemplateMarkup *markup,
+                                                       glLabel                 *label);
+
+static void       gl_cairo_markup_margin_cd_path      (cairo_t                 *cr,
+                                                       const lglTemplateMarkup *markup,
+                                                       glLabel                 *label);
+
+static void       gl_cairo_markup_line_path           (cairo_t                 *cr,
+                                                       const lglTemplateMarkup *markup);
+
+static void       gl_cairo_markup_circle_path         (cairo_t                 *cr,
+                                                       const lglTemplateMarkup *markup);
+
+static void       gl_cairo_markup_rect_path           (cairo_t                 *cr,
+                                                       const lglTemplateMarkup *markup);
+
+
+/*--------------------------------------------------------------------------*/
+/* Create markup path                                                       */
+/*--------------------------------------------------------------------------*/
+void
+gl_cairo_markup_path (cairo_t                 *cr,
+                      const lglTemplateMarkup *markup,
+                      glLabel                 *label)
+{
+        gl_debug (DEBUG_PATH, "START");
+
+        switch (markup->type) {
+        case LGL_TEMPLATE_MARKUP_MARGIN:
+                gl_cairo_markup_margin_path (cr, markup, label);
+                break;
+        case LGL_TEMPLATE_MARKUP_LINE:
+                gl_cairo_markup_line_path (cr, markup);
+                break;
+        case LGL_TEMPLATE_MARKUP_CIRCLE:
+                gl_cairo_markup_circle_path (cr, markup);
+                break;
+        case LGL_TEMPLATE_MARKUP_RECT:
+                gl_cairo_markup_rect_path (cr, markup);
+                break;
+        default:
+                g_message ("Unknown template markup type");
+                break;
+        }
+
+        gl_debug (DEBUG_PATH, "END");
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw margin markup.                                             */
+/*---------------------------------------------------------------------------*/
+static void
+gl_cairo_markup_margin_path (cairo_t                *cr,
+                             const lglTemplateMarkup *markup,
+                             glLabel                *label)
+{
+       const lglTemplateFrame *frame;
+
+        gl_debug (DEBUG_PATH, "START");
+
+        frame = (lglTemplateFrame *)label->template->frames->data;
+
+        switch (frame->shape) {
+
+        case LGL_TEMPLATE_FRAME_SHAPE_RECT:
+                gl_cairo_markup_margin_rect_path (cr, markup, label);
+                break;
+
+        case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
+                gl_cairo_markup_margin_round_path (cr, markup, label);
+                break;
+
+        case LGL_TEMPLATE_FRAME_SHAPE_CD:
+                gl_cairo_markup_margin_cd_path (cr, markup, label);
+                break;
+
+        default:
+                g_message ("Unknown template label style");
+                break;
+        }
+
+        gl_debug (DEBUG_PATH, "END");
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw simple recangular margin.                                  */
+/*---------------------------------------------------------------------------*/
+static void
+gl_cairo_markup_margin_rect_path (cairo_t                 *cr,
+                                  const lglTemplateMarkup *markup,
+                                  glLabel                 *label)
+{
+        const lglTemplateFrame *frame;
+        gdouble                 w, h, r, m;
+
+        gl_debug (DEBUG_PATH, "START");
+
+        frame = (lglTemplateFrame *)label->template->frames->data;
+
+        m = markup->margin.size;
+
+        lgl_template_frame_get_size (frame, &w, &h);
+       w = w - 2*m;
+       h = h - 2*m;
+        r = MAX (frame->rect.r - m, 0.0);
+
+        if ( r == 0.0 )
+        {
+                cairo_rectangle (cr, m, m, w, h);
+        }
+        else
+        {
+                cairo_new_path (cr);
+                cairo_arc_negative (cr, m+r,   m+r,   r, 3*G_PI/2, G_PI);
+                cairo_arc_negative (cr, m+r,   m+h-r, r, G_PI,     G_PI/2);
+                cairo_arc_negative (cr, m+w-r, m+h-r, r, G_PI/2,   0.);
+                cairo_arc_negative (cr, m+w-r, m+r,   r, 2*G_PI,   3*G_PI/2);
+                cairo_close_path (cr);
+        }
+
+        gl_debug (DEBUG_PATH, "END");
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw round margin.                                              */
+/*---------------------------------------------------------------------------*/
+static void
+gl_cairo_markup_margin_round_path (cairo_t                 *cr,
+                                   const lglTemplateMarkup *markup,
+                                   glLabel                 *label)
+{
+       const lglTemplateFrame *frame;
+       gdouble                 r, m;
+
+       gl_debug (DEBUG_PATH, "START");
+
+        frame = (lglTemplateFrame *)label->template->frames->data;
+
+       r = frame->round.r;
+       m = markup->margin.size;
+
+        cairo_arc (cr, r, r, r-m, 0, 2*G_PI);
+        cairo_close_path (cr);
+
+       gl_debug (DEBUG_PATH, "END");
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw CD margins.                                                */
+/*---------------------------------------------------------------------------*/
+static void
+gl_cairo_markup_margin_cd_path (cairo_t                 *cr,
+                                const lglTemplateMarkup *markup,
+                                glLabel                 *label)
+{
+       const lglTemplateFrame *frame;
+       gdouble                 m, r1, r2;
+       gdouble                 theta1, theta2;
+       gdouble                 xc, yc;
+       gdouble                 w, h;
+
+       gl_debug (DEBUG_PATH, "START");
+
+        frame = (lglTemplateFrame *)label->template->frames->data;
+
+        lgl_template_frame_get_size (frame, &w, &h);
+        xc = w/2.0;
+        yc = h/2.0;
+
+       m  = markup->margin.size;
+        r1 = frame->cd.r1 - m;
+        r2 = frame->cd.r2 + m;
+
+
+        /*
+         * Outer path (may be clipped)
+         */
+        theta1 = acos ((w-2*m) / (2.0*r1));
+        theta2 = asin ((h-2*m) / (2.0*r1));
+
+        cairo_new_path (cr);
+        cairo_arc (cr, xc, yc, r1, theta1, theta2);
+        cairo_arc (cr, xc, yc, r1, G_PI-theta2, G_PI-theta1);
+        cairo_arc (cr, xc, yc, r1, G_PI+theta1, G_PI+theta2);
+        cairo_arc (cr, xc, yc, r1, 2*G_PI-theta2, 2*G_PI-theta1);
+        cairo_close_path (cr);
+
+
+        /* Inner path (hole) */
+        cairo_new_sub_path (cr);
+        cairo_arc (cr, xc, yc, r2, 0.0, 2*G_PI);
+        cairo_close_path (cr);
+
+       gl_debug (DEBUG_PATH, "END");
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw line markup.                                               */
+/*---------------------------------------------------------------------------*/
+static void
+gl_cairo_markup_line_path (cairo_t                 *cr,
+                           const lglTemplateMarkup *markup)
+{
+       gl_debug (DEBUG_PATH, "START");
+
+        cairo_move_to (cr, markup->line.x1, markup->line.y1);
+        cairo_line_to (cr, markup->line.x2, markup->line.y2);
+
+       gl_debug (DEBUG_PATH, "END");
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw circle markup.                                             */
+/*---------------------------------------------------------------------------*/
+static void
+gl_cairo_markup_circle_path (cairo_t                 *cr,
+                             const lglTemplateMarkup *markup)
+{
+       gl_debug (DEBUG_PATH, "START");
+
+        cairo_arc (cr,
+                   markup->circle.x0, markup->circle.y0,
+                   markup->circle.r,
+                   0.0, 2*G_PI);
+        cairo_close_path (cr);
+
+       gl_debug (DEBUG_PATH, "END");
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Draw rect markup.                                               */
+/*---------------------------------------------------------------------------*/
+static void
+gl_cairo_markup_rect_path (cairo_t                 *cr,
+                           const lglTemplateMarkup *markup)
+{
+        gdouble x1 = markup->rect.x1;
+        gdouble y1 = markup->rect.y1;
+        gdouble w  = markup->rect.w;
+        gdouble h  = markup->rect.h;
+        gdouble r  = markup->rect.r;
+
+       gl_debug (DEBUG_PATH, "START");
+
+        if ( r == 0.0 )
+        {
+                cairo_rectangle (cr, x1, y1, w, h);
+        }
+        else
+        {
+                cairo_new_path (cr);
+                cairo_arc_negative (cr, x1+r,   y1+r,   r, 3*G_PI/2, G_PI);
+                cairo_arc_negative (cr, x1+r,   y1+h-r, r, G_PI,     G_PI/2);
+                cairo_arc_negative (cr, x1+w-r, y1+h-r, r, G_PI/2,   0.);
+                cairo_arc_negative (cr, x1+w-r, y1+r,   r, 2*G_PI,   3*G_PI/2);
+                cairo_close_path (cr);
+        }
+
+       gl_debug (DEBUG_PATH, "END");
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */