[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