[cairo] [PATCH 01/39] [OpenVG] Build plumbing and addition of OpenVG surface type, and added initial skeleton of backend.

tardyp at gmail.com tardyp at gmail.com
Fri Jul 10 10:02:03 PDT 2009


From: Øyvind Kolås <pippin at gimp.org>

---
 src/cairo-openvg-surface.c |  498 ++++++++++++++++++++++++++++++++++++++++++++
 src/cairo-openvg.h         |   47 ++++
 src/cairo.h                |    4 +-
 3 files changed, 548 insertions(+), 1 deletions(-)
 create mode 100644 src/cairo-openvg-surface.c
 create mode 100644 src/cairo-openvg.h

diff --git a/src/cairo-openvg-surface.c b/src/cairo-openvg-surface.c
new file mode 100644
index 0000000..9a1bdfc
--- /dev/null
+++ b/src/cairo-openvg-surface.c
@@ -0,0 +1,498 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyight (c) 2007 Mozilla Corporation
+ *
+ * This libary is free software; you can redistribute it and/or
+ * modify it eithe under the terms of the GNU Lesser General Public
+ * License vesion 2.1 as published by the Free Software Foundation
+ * (the "LGPL") o, at your option, under the terms of the Mozilla
+ * Public License Vesion 1.1 (the "MPL"). If you do not alter this
+ * notice, a ecipient may use your version of this file under either
+ * the MPL o the LGPL.
+ *
+ * You should have eceived a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, wite to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have eceived a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file ae subject to the Mozilla Public License
+ * Vesion 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.og/MPL/
+ *
+ * This softwae is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, eithe express or implied. See the LGPL or the MPL for
+ * the specific language govening rights and limitations.
+ *
+ * The Oiginal Code is the cairo graphics library.
+ *
+ * The Initial Develope of the Original Code is Mozilla Corporation.
+ *
+ * Contibutor(s):
+ *      Vladimi Vukicevic <vladimir at mozilla.com>
+ */
+
+#include "cairoint.h"
+#include "cairo-openvg.h"
+#include <VG/openvg.h>
+
+typedef struct cairo_openvg_surface {
+    cairo_surface_t base;
+    cairo_content_t content;
+    int             width;
+    int             height;
+} cairo_openvg_surface_t;
+
+static cairo_surface_t *
+_cairo_openvg_surface_create_similar (void *asurface,
+                                   cairo_content_t content,
+                                   int width,
+                                   int height)
+{
+    return cairo_openvg_surface_create(width, height);
+}
+
+static cairo_status_t
+_cairo_openvg_surface_clone_similar (void *asurface,
+                                  cairo_surface_t *src,
+                                  int sc_x,
+                                  int sc_y,
+                                  int width,
+                                  int height,
+                                  cairo_surface_t **clone_out)
+{
+    *clone_out = cairo_openvg_surface_create(width ,height);
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_openvg_surface_intersect_clip_path (void *asurface,
+                                        cairo_path_fixed_t *path,
+                                        cairo_fill_rule_t fill_rule,
+                                        double toleance,
+                                        cairo_antialias_t antialias)
+{
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_openvg_surface_get_extents (void *asurface,
+                                cairo_rectangle_int_t *extents)
+{
+    extents->x = 0;
+    extents->y = 0;
+    extents->width = 0;
+    extents->height = 0;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_openvg_surface_paint (void *asurface,
+                             cairo_operator_t op,
+                             cairo_pattern_t *source)
+{
+    cairo_openvg_surface_t *s = asurface;
+
+    if (source->type == CAIRO_PATTERN_TYPE_SOLID)
+      {
+        cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
+        VGfloat color[] = {solid->color.red,
+                           solid->color.green,
+                           solid->color.blue,
+                           solid->color.alpha};
+        vgSetfv (VG_CLEAR_COLOR, 4, color);
+        vgClear (0, 0, s->width * 3, s->height * 2);
+      }
+    else
+      {
+        printf ("not supporting source of type %i for paint yet", source->type);
+      }
+
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_openvg_surface_mask (void *asurface,
+                         cairo_operator_t op,
+                         cairo_pattern_t *source,
+                         cairo_pattern_t *mask)
+{
+    printf ("mask\n");
+    return CAIRO_STATUS_SUCCESS;
+}
+
+typedef struct _openvg_stroke {
+  VGPath path;
+  cairo_matrix_t *ctm_inverse; /* useful for somthing? */
+} openvg_stroke_t;
+
+static cairo_status_t
+_cairo_path_to_openvg_path_move_to (void *closure, cairo_point_t *point)
+{
+  VGubyte seg[1]={VG_MOVE_TO};
+  VGfloat data[4];
+
+  openvg_stroke_t *stroke = closure;
+  double x = _cairo_fixed_to_double (point->x);
+  double y = _cairo_fixed_to_double (point->y);
+
+  if (stroke->ctm_inverse)
+    cairo_matrix_transform_point (stroke->ctm_inverse, &x, &y);
+
+  data[0] = x;
+  data[1] = y;
+
+  vgAppendPathData(stroke->path, 1, seg, data);
+  return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_path_to_openvg_path_line_to (void *closure, cairo_point_t *point)
+{
+  VGubyte seg[1]={VG_LINE_TO};
+  VGfloat data[4];
+
+  openvg_stroke_t *stroke = closure;
+  double x = _cairo_fixed_to_double (point->x);
+  double y = _cairo_fixed_to_double (point->y);
+
+  if (stroke->ctm_inverse)
+    cairo_matrix_transform_point (stroke->ctm_inverse, &x, &y);
+
+  data[0] = x;
+  data[1] = y;
+
+  vgAppendPathData(stroke->path, 1, seg, data);
+  return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_path_to_openvg_path_curve_to (void *closure, cairo_point_t *p0,
+                                                    cairo_point_t *p1,
+                                                    cairo_point_t *p2)
+{
+  VGubyte seg[1]={VG_CUBIC_TO};
+  VGfloat data[6];
+
+  openvg_stroke_t *stroke = closure;
+  double x0 = _cairo_fixed_to_double (p0->x);
+  double y0 = _cairo_fixed_to_double (p0->y);
+  double x1 = _cairo_fixed_to_double (p1->x);
+  double y1 = _cairo_fixed_to_double (p1->y);
+  double x2 = _cairo_fixed_to_double (p2->x);
+  double y2 = _cairo_fixed_to_double (p2->y);
+
+  if (stroke->ctm_inverse)
+    {
+      cairo_matrix_transform_point (stroke->ctm_inverse, &x0, &y0);
+      cairo_matrix_transform_point (stroke->ctm_inverse, &x1, &y1);
+      cairo_matrix_transform_point (stroke->ctm_inverse, &x2, &y2);
+    }
+
+  data[0] = x0;
+  data[1] = y0;
+  data[2] = x1;
+  data[3] = y1;
+  data[4] = x2;
+  data[5] = y2;
+
+  vgAppendPathData(stroke->path, 1, seg, data);
+  return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_path_to_openvg_path_close_path (void *closure)
+{
+  VGubyte seg[1]={VG_CLOSE_PATH};
+  VGfloat data[4];
+
+  openvg_stroke_t *stroke = closure;
+
+  vgAppendPathData(stroke->path, 1, seg, data);
+
+  return CAIRO_STATUS_SUCCESS;
+}
+
+
+static cairo_status_t
+_cairo_quartz_cairo_path_to_openvg_path (cairo_path_fixed_t *path,
+					 openvg_stroke_t    *stroke)
+{
+    return _cairo_path_fixed_interpret (path,
+					CAIRO_DIRECTION_FORWARD,
+					_cairo_path_to_openvg_path_move_to,
+					_cairo_path_to_openvg_path_line_to,
+					_cairo_path_to_openvg_path_curve_to,
+					_cairo_path_to_openvg_path_close_path,
+					stroke);
+}
+
+
+/*
+ * Misc helpers/callbacks
+ */
+
+static VGBlendMode
+_cairo_openvg_cairo_operator_to_openvg (cairo_operator_t op)
+{
+    switch (op) {
+	/*case CAIRO_OPERATOR_CLEAR:
+	    return kPrivateCGCompositeClear;*/
+	case CAIRO_OPERATOR_SOURCE:
+	    return VG_BLEND_SRC;
+	case CAIRO_OPERATOR_OVER:
+	    return VG_BLEND_SRC_OVER;
+	case CAIRO_OPERATOR_IN:
+            return VG_BLEND_SRC_IN;
+	case CAIRO_OPERATOR_OUT:
+	case CAIRO_OPERATOR_ATOP:
+	    return VG_BLEND_SRC_ATOP_SH;
+	case CAIRO_OPERATOR_DEST:
+	case CAIRO_OPERATOR_DEST_OVER:
+	case CAIRO_OPERATOR_DEST_IN:
+	case CAIRO_OPERATOR_DEST_OUT:
+	case CAIRO_OPERATOR_DEST_ATOP:
+	case CAIRO_OPERATOR_XOR:
+	case CAIRO_OPERATOR_ADD:
+	case CAIRO_OPERATOR_SATURATE:
+	case CAIRO_OPERATOR_CLEAR:
+            return VG_BLEND_MULTIPLY;
+    }
+
+    return VG_BLEND_SRC_OVER;
+}
+
+static VGCapStyle
+_cairo_openvg_cairo_line_cap_to_openvg (cairo_line_cap_t ccap)
+{
+    switch (ccap) {
+	case CAIRO_LINE_CAP_BUTT: return VG_CAP_BUTT; break;
+	case CAIRO_LINE_CAP_ROUND: return VG_CAP_ROUND; break;
+	case CAIRO_LINE_CAP_SQUARE: return VG_CAP_SQUARE; break;
+    }
+
+    return VG_CAP_BUTT;
+}
+
+static VGJoinStyle
+_cairo_openvg_cairo_line_join_to_openvg (cairo_line_join_t cjoin)
+{
+    switch (cjoin) {
+	case CAIRO_LINE_JOIN_MITER: return VG_JOIN_MITER; break;
+	case CAIRO_LINE_JOIN_ROUND: return VG_JOIN_ROUND; break;
+	case CAIRO_LINE_JOIN_BEVEL: return VG_JOIN_BEVEL; break;
+    }
+
+    return VG_JOIN_MITER;
+}
+
+#if 0
+typedef struct _cairo_matrix {
+    double xx; double yx;
+    double xy; double yy;
+    double x0; double y0;
+} cairo_matrix_t;
+#endif
+
+/* { sx, shy, w0, shx, sy, w1, tx, ty, w2 } */
+
+static void
+_cairo_openvg_cairo_matrix_to_openvg (const cairo_matrix_t *src,
+				      VGfloat *dst
+                                      
+                                      )
+{
+  /*VGfloat state[9];*/
+#if 0
+    dst->a = src->xx;
+    dst->b = src->yx;
+    dst->c = src->xy;
+    dst->d = src->yy;
+    dst->tx = src->x0;
+    dst->ty = src->y0;
+#endif
+    dst[0] = /* sx  */ src->xx;
+    dst[1] = /* shy */ src->yx;
+    dst[2] = /* w0  */ 0;
+    dst[3] = /* shx */ src->xy;
+    dst[4] = /* sy  */ src->yy;
+    dst[5] = /* w1  */ 0;
+    dst[6] = /* tx  */ src->x0;
+    dst[7] = /* ty  */ src->y0;
+    dst[8] = /* w2  */ 0;
+}
+
+static void setup_source (VGPaint paint,
+                          cairo_pattern_t *source)
+{
+
+  if (source->type == CAIRO_PATTERN_TYPE_SOLID)
+    {
+      cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
+      VGfloat color[] = {solid->color.red,
+                         solid->color.green,
+                         solid->color.blue,
+                         solid->color.alpha};
+      vgSetParameterfv (paint, VG_PAINT_COLOR, 4, color);
+    }
+  else
+    {
+      printf ("not handling source of type: %i\n", source->type);
+    }
+}
+
+static cairo_int_status_t
+_cairo_openvg_surface_stroke (void *asurface,
+                              cairo_operator_t op,
+                              cairo_pattern_t *source,
+                              cairo_path_fixed_t *path,
+                              cairo_stroke_style_t *style,
+                              cairo_matrix_t *ctm,
+                              cairo_matrix_t *ctm_inverse,
+                              double toleance,
+                              cairo_antialias_t antialias)
+{
+  VGfloat state[9];
+  VGfloat strokeTransform[9];
+  openvg_stroke_t vg_path;
+  VGPaint paint;
+
+  vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
+                               VG_PATH_DATATYPE_F,
+                               1, 0, 0, 0, VG_PATH_CAPABILITY_ALL);
+
+  vgGetMatrix (state);
+  _cairo_openvg_cairo_matrix_to_openvg (ctm, strokeTransform);
+  vgMultMatrix (strokeTransform);
+
+  vg_path.ctm_inverse = ctm_inverse;
+
+  _cairo_quartz_cairo_path_to_openvg_path (path, &vg_path);
+
+  vgSetf (VG_STROKE_LINE_WIDTH, style->line_width);
+
+  vgSetf (VG_STROKE_MITER_LIMIT, style->miter_limit);
+  vgSetf(VG_STROKE_JOIN_STYLE,
+         _cairo_openvg_cairo_line_join_to_openvg (style->line_join));
+  vgSetf(VG_STROKE_CAP_STYLE,
+         _cairo_openvg_cairo_line_cap_to_openvg (style->line_cap));
+
+  vgSeti(VG_BLEND_MODE, _cairo_openvg_cairo_operator_to_openvg (op));
+
+  paint = vgCreatePaint();
+
+  setup_source (paint, source);
+
+  vgSetPaint(paint, VG_STROKE_PATH);
+
+
+  vgDrawPath (vg_path.path, VG_STROKE_PATH);
+  vgDestroyPaint (paint);
+  vgDestroyPath (vg_path.path);
+
+  vgLoadMatrix (state);
+
+  return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_openvg_surface_fill (void *asurface,
+                         cairo_operator_t op,
+                         cairo_pattern_t *source,
+                         cairo_path_fixed_t *path,
+                         cairo_fill_rule_t fill_rule,
+                         double toleance,
+                         cairo_antialias_t antialias)
+{
+  openvg_stroke_t vg_path;
+  VGPaint paint;
+
+  vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
+                               VG_PATH_DATATYPE_F,
+                               1,0,0,0, VG_PATH_CAPABILITY_ALL);
+  vg_path.ctm_inverse = NULL;
+
+  _cairo_quartz_cairo_path_to_openvg_path (path, &vg_path);
+
+  vgSeti(VG_BLEND_MODE, _cairo_openvg_cairo_operator_to_openvg (op));
+
+  paint = vgCreatePaint();
+
+  setup_source (paint, source);
+
+  vgSetPaint(paint, VG_FILL_PATH);
+  vgDrawPath (vg_path.path, VG_FILL_PATH);
+  vgDestroyPaint (paint);
+  vgDestroyPath (vg_path.path);
+
+  return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_openvg_surface_show_glyphs (void *asurface,
+                                cairo_operator_t op,
+                                cairo_pattern_t *source,
+                                cairo_glyph_t *glyphs,
+                                int num_glyphs,
+                                cairo_scaled_font_t *scaled_font)
+{
+    printf ("show_glyphs\n");
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static const struct _cairo_surface_backend
+cairo_openvg_surface_backend = {
+    CAIRO_SURFACE_TYPE_OPENVG,
+    _cairo_openvg_surface_create_similar,
+    NULL, /* finish */
+    NULL, /* acquie_source_image */
+    NULL, /* elease_source_image */
+    NULL, /* acquie_dest_image */
+    NULL, /* elease_dest_image */
+    _cairo_openvg_surface_clone_similar,
+    NULL, /* composite */
+    NULL, /* fill_ectangles */
+    NULL, /* composite_tapezoids */
+    NULL, /* copy_page */
+    NULL, /* show_page */
+    NULL, /* set_clip_egion */
+    _cairo_openvg_surface_intersect_clip_path,
+    _cairo_openvg_surface_get_extents,
+    NULL, /* old_show_glyphs */
+    NULL, /* get_font_options */
+    NULL, /* flush */
+    NULL, /* mak_dirty_rectangle */
+    NULL, /* scaled_font_fini */
+    NULL, /* scaled_glyph_fini */
+
+    _cairo_openvg_surface_paint,
+    _cairo_openvg_surface_mask,
+    _cairo_openvg_surface_stroke,
+    _cairo_openvg_surface_fill,
+    NULL, /* _cairo_openvg_surface_show_glyphs, */
+
+    NULL, /* snapshot */
+    NULL, /* is_simila */
+    NULL, /* eset */
+};
+
+cairo_surface_t *
+cairo_openvg_surface_create (int width, int height)
+{
+    cairo_openvg_surface_t *s = malloc(sizeof(cairo_openvg_surface_t));
+    memset(s, 0, sizeof(cairo_openvg_surface_t));
+    _cairo_surface_init(&s->base, &cairo_openvg_surface_backend, CAIRO_CONTENT_COLOR_ALPHA);
+    s->width = width;
+    s->height = height;
+
+
+    vgLoadIdentity();
+    vgTranslate (-1.0, 1.0);
+    vgScale (2.0/width, -2.0/height);
+
+    return (cairo_surface_t *) s;
+}
diff --git a/src/cairo-openvg.h b/src/cairo-openvg.h
new file mode 100644
index 0000000..24f0844
--- /dev/null
+++ b/src/cairo-openvg.h
@@ -0,0 +1,47 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2007 Mozilla Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ *
+ * Contributor(s):
+ *      Vladimir Vukicevic <vladimir at mozilla.com>
+ */
+
+#ifndef CAIRO_OPENVG_H
+#define CAIRO_OPENVG_H
+
+CAIRO_BEGIN_DECLS
+
+cairo_public cairo_surface_t *
+cairo_openvg_surface_create (int width, int height);
+
+CAIRO_END_DECLS
+
+#endif /* CAIRO_OPENVG_H */
diff --git a/src/cairo.h b/src/cairo.h
index 8f7e533..6219fac 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -1891,6 +1891,7 @@ cairo_surface_status (cairo_surface_t *surface);
  * @CAIRO_SURFACE_TYPE_SCRIPT: The surface is of type script, since 1.10
  * @CAIRO_SURFACE_TYPE_QT: The surface is of type Qt, since 1.10
  * @CAIRO_SURFACE_TYPE_META: The surface is a meta-type, since 1.10
+ * @CAIRO_SURFACE_TYPE_OPENVG: The surface is a OpenVG surface
  *
  * #cairo_surface_type_t is used to describe the type of a given
  * surface. The surface types are also known as "backends" or "surface
@@ -1932,7 +1933,8 @@ typedef enum _cairo_surface_type {
     CAIRO_SURFACE_TYPE_QUARTZ_IMAGE,
     CAIRO_SURFACE_TYPE_SCRIPT,
     CAIRO_SURFACE_TYPE_QT,
-    CAIRO_SURFACE_TYPE_META
+    CAIRO_SURFACE_TYPE_META,
+    CAIRO_SURFACE_TYPE_OPENVG
 } cairo_surface_type_t;
 
 cairo_public cairo_surface_type_t
-- 
1.6.0.4



More information about the cairo mailing list