summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: dd1787f)
raw | patch | inline | side by side (parent: dd1787f)
author | buliabyak <buliabyak@users.sourceforge.net> | |
Thu, 1 Mar 2007 04:15:17 +0000 (04:15 +0000) | ||
committer | buliabyak <buliabyak@users.sourceforge.net> | |
Thu, 1 Mar 2007 04:15:17 +0000 (04:15 +0000) |
src/display/Makefile_insert | patch | blob | history | |
src/display/inkscape-cairo.cpp | [new file with mode: 0644] | patch | blob |
src/display/inkscape-cairo.h | [new file with mode: 0644] | patch | blob |
src/display/nr-arena-glyphs.cpp | patch | blob | history | |
src/display/nr-arena-shape.cpp | patch | blob | history |
index 4d51a789107923f664a5de1fa80c1c2160faf660..ad69c772b0b26a5bda243cbafecc8016720c0a7e 100644 (file)
display/pixblock-scaler.cpp \
display/pixblock-scaler.h \
display/pixblock-transform.cpp \
- display/pixblock-transform.h
+ display/pixblock-transform.h \
+ display/inkscape-cairo.cpp \
+ display/inkscape-cairo.h
display_bezier_utils_test_SOURCES = display/bezier-utils-test.cpp
display_bezier_utils_test_LDADD = libnr/libnr.a -lglib-2.0
diff --git a/src/display/inkscape-cairo.cpp b/src/display/inkscape-cairo.cpp
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Helper functions to use cairo with inkscape
+ *
+ * Copyright (C) 2007 bulia byak
+ *
+ * Released under GNU GPL
+ *
+ */
+
+#include <cairo.h>
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <libnr/n-art-bpath.h>
+#include <libnr/nr-matrix-ops.h>
+#include <libnr/nr-matrix-fns.h>
+#include <libnr/nr-pixblock.h>
+#include "../style.h"
+#include "nr-arena.h"
+
+
+/** Creates a cairo context to render to the given pixblock on the given area */
+cairo_t *
+nr_create_cairo_context (NRRectL *area, NRPixBlock *pb)
+{
+ if (!nr_rect_l_test_intersect (&pb->area, area))
+ return NULL;
+
+ NRRectL clip;
+ nr_rect_l_intersect (&clip, &pb->area, area);
+ unsigned char *dpx = NR_PIXBLOCK_PX (pb) + (clip.y0 - pb->area.y0) * pb->rs + NR_PIXBLOCK_BPP (pb) * (clip.x0 - pb->area.x0);
+ int width = area->x1 - area->x0;
+ int height = area->y1 - area->y0;
+ // even though cairo cannot draw in nonpremul mode, select ARGB32 for R8G8B8A8N as the closest; later eliminate R8G8B8A8N everywhere
+ cairo_surface_t* cst = cairo_image_surface_create_for_data
+ (dpx,
+ ((pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P || pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N) ? CAIRO_FORMAT_ARGB32 : (pb->mode == NR_PIXBLOCK_MODE_R8G8B8? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_A8)),
+ width,
+ height,
+ pb->rs);
+ cairo_t *ct = cairo_create (cst);
+
+ return ct;
+}
+
+/** Feeds path-creating calls to the cairo context translating them from the SPCurve, with the given transform and shift */
+void
+feed_curve_to_cairo (cairo_t *ct, NArtBpath *bpath, NR::Matrix trans, NR::Point shift)
+{
+ NR::Point lastX(0,0);
+ bool closed = false;
+ for (int i = 0; bpath[i].code != NR_END; i++) {
+ switch (bpath[i].code) {
+ case NR_MOVETO_OPEN:
+ case NR_MOVETO:
+ if (closed) cairo_close_path(ct);
+ closed = (bpath[i].code == NR_MOVETO);
+ lastX[NR::X] = bpath[i].x3;
+ lastX[NR::Y] = bpath[i].y3;
+ lastX *= trans;
+ lastX -= shift;
+ cairo_move_to(ct, lastX[NR::X], lastX[NR::Y]);
+ break;
+
+ case NR_LINETO:
+ lastX[NR::X] = bpath[i].x3;
+ lastX[NR::Y] = bpath[i].y3;
+ lastX *= trans;
+ lastX -= shift;
+ cairo_line_to(ct, lastX[NR::X], lastX[NR::Y]);
+ break;
+
+ case NR_CURVETO: {
+ NR::Point tm1, tm2, tm3;
+ tm1[0]=bpath[i].x1;
+ tm1[1]=bpath[i].y1;
+ tm2[0]=bpath[i].x2;
+ tm2[1]=bpath[i].y2;
+ tm3[0]=bpath[i].x3;
+ tm3[1]=bpath[i].y3;
+ tm1 *= trans;
+ tm2 *= trans;
+ tm3 *= trans;
+ tm1 -= shift;
+ tm2 -= shift;
+ tm3 -= shift;
+ cairo_curve_to (ct, tm1[NR::X], tm1[NR::Y], tm2[NR::X], tm2[NR::Y], tm3[NR::X], tm3[NR::Y]);
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/display/inkscape-cairo.h b/src/display/inkscape-cairo.h
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef __INKSCAPE_CAIRO_H__
+#define __INKSCAPE_CAIRO_H__
+
+/*
+ * Helper functions to use cairo with inkscape
+ *
+ * Copyright (C) 2007 bulia byak
+ *
+ * Released under GNU GPL
+ *
+ */
+
+cairo_t *nr_create_cairo_context (NRRectL *area, NRPixBlock *pb);
+void feed_curve_to_cairo (cairo_t *ct, NArtBpath *bpath, NR::Matrix trans, NR::Point shift);
+
+#endif
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index b9f962284553fea7eaffe33b98241a5ab08faf2a..a29c44ee14bc6bbb33073faf121c65aacf9b3544 100644 (file)
#endif
#include <libnr/nr-blit.h>
#include <libnr/nr-path.h>
+#include <libnr/n-art-bpath.h>
+#include <libnr/nr-matrix-ops.h>
+#include <libnr/nr-matrix-fns.h>
#include "../style.h"
#include "nr-arena.h"
#include "nr-arena-glyphs.h"
+#include <cairo.h>
+#include "inkscape-cairo.h"
#ifdef test_glyph_liv
#include "../display/canvas-bpath.h"
@@ -423,7 +428,6 @@ nr_arena_glyphs_group_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint s
return NR_ARENA_ITEM_STATE_ALL;
}
-/* This sucks - as soon, as we have inheritable renderprops, do something with that opacity */
static unsigned int
nr_arena_glyphs_group_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags)
@@ -436,6 +440,40 @@ nr_arena_glyphs_group_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, u
guint ret = item->state;
+ if (item->arena->rendermode == RENDERMODE_OUTLINE) {
+
+ cairo_t *ct = nr_create_cairo_context (area, pb);
+
+ if (!ct)
+ return item->state;
+
+ guint32 rgba = item->arena->outlinecolor;
+ cairo_set_source_rgba(ct, SP_RGBA32_R_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_B_F(rgba), SP_RGBA32_A_F(rgba));
+ cairo_set_tolerance(ct, 1.25); // low quality, but good enough for outline mode
+
+ for (child = group->children; child != NULL; child = child->next) {
+ NRArenaGlyphs *g = NR_ARENA_GLYPHS(child);
+
+ NArtBpath *bpath = (NArtBpath *) g->font->ArtBPath(g->glyph);
+
+ cairo_new_path(ct);
+ NR::Matrix g_t(g->g_transform);
+ feed_curve_to_cairo (ct, bpath, g_t * group->ctm, NR::Point(area->x0, area->y0));
+ cairo_fill(ct);
+ }
+
+ cairo_surface_t *cst = cairo_get_target(ct);
+ cairo_destroy (ct);
+ cairo_surface_finish (cst);
+ cairo_surface_destroy (cst);
+
+ pb->empty = FALSE;
+ return ret;
+ }
+
+
+
+
/* Fill */
if (style->fill.type != SP_PAINT_TYPE_NONE || item->arena->rendermode == RENDERMODE_OUTLINE) {
NRPixBlock m;
index 2e15ac5aa902d580bf840c70d0138161007a74a2..d6b3bc73b3262d87a3fdf2799230f926b8214ba9 100644 (file)
#include "prefs-utils.h"
#include "sp-filter.h"
#include "sp-gaussian-blur.h"
+#include "inkscape-cairo.h"
#include <cairo.h>
}
}
-/** Feeds path-creating calls to the cairo context translating them from the SPCurve, with the given transform and shift */
-static void
-feed_curve_to_cairo (cairo_t *ct, SPCurve *curve, NR::Matrix trans, NR::Point shift)
-{
- NR::Point lastX(0,0);
- bool closed = false;
- NArtBpath *bpath = SP_CURVE_BPATH(curve);
- for (int i = 0; bpath[i].code != NR_END; i++) {
- switch (bpath[i].code) {
- case NR_MOVETO_OPEN:
- case NR_MOVETO:
- if (closed) cairo_close_path(ct);
- closed = (bpath[i].code == NR_MOVETO);
- lastX[NR::X] = bpath[i].x3;
- lastX[NR::Y] = bpath[i].y3;
- lastX *= trans;
- lastX -= shift;
- cairo_move_to(ct, lastX[NR::X], lastX[NR::Y]);
- break;
-
- case NR_LINETO:
- lastX[NR::X] = bpath[i].x3;
- lastX[NR::Y] = bpath[i].y3;
- lastX *= trans;
- lastX -= shift;
- cairo_line_to(ct, lastX[NR::X], lastX[NR::Y]);
- break;
-
- case NR_CURVETO: {
- NR::Point tm1, tm2, tm3;
- tm1[0]=bpath[i].x1;
- tm1[1]=bpath[i].y1;
- tm2[0]=bpath[i].x2;
- tm2[1]=bpath[i].y2;
- tm3[0]=bpath[i].x3;
- tm3[1]=bpath[i].y3;
- tm1 *= trans;
- tm2 *= trans;
- tm3 *= trans;
- tm1 -= shift;
- tm2 -= shift;
- tm3 -= shift;
- cairo_curve_to (ct, tm1[NR::X], tm1[NR::Y], tm2[NR::X], tm2[NR::Y], tm3[NR::X], tm3[NR::Y]);
- break;
- }
-
- default:
- break;
- }
- }
-}
-
-/** Creates a cairo context to render to the given pixblock on the given area */
-cairo_t *
-nr_create_cairo_context (NRRectL *area, NRPixBlock *pb)
-{
- if (!nr_rect_l_test_intersect (&pb->area, area))
- return NULL;
-
- NRRectL clip;
- nr_rect_l_intersect (&clip, &pb->area, area);
- unsigned char *dpx = NR_PIXBLOCK_PX (pb) + (clip.y0 - pb->area.y0) * pb->rs + NR_PIXBLOCK_BPP (pb) * (clip.x0 - pb->area.x0);
- int width = area->x1 - area->x0;
- int height = area->y1 - area->y0;
- // even though cairo cannot draw in nonpremul mode, select ARGB32 for R8G8B8A8N as the closest; later eliminate R8G8B8A8N everywhere
- cairo_surface_t* cst = cairo_image_surface_create_for_data
- (dpx,
- ((pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P || pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N) ? CAIRO_FORMAT_ARGB32 : (pb->mode == NR_PIXBLOCK_MODE_R8G8B8? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_A8)),
- width,
- height,
- pb->rs);
- cairo_t *ct = cairo_create (cst);
-
- return ct;
-}
-
// cairo outline rendering:
static unsigned int
cairo_arena_shape_render_outline(NRArenaItem *item, NRRectL *area, NRPixBlock *pb)
@@ -819,7 +744,7 @@ cairo_arena_shape_render_outline(NRArenaItem *item, NRRectL *area, NRPixBlock *p
cairo_set_tolerance(ct, 1.25); // low quality, but good enough for outline mode
cairo_new_path(ct);
- feed_curve_to_cairo (ct, shape->curve, NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0));
+ feed_curve_to_cairo (ct, SP_CURVE_BPATH(shape->curve), NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0));
cairo_stroke(ct);
@@ -908,7 +833,7 @@ cairo_arena_shape_render_stroke(NRArenaItem *item, NRRectL *area, NRPixBlock *pb
cairo_set_tolerance(ct, 0.1);
cairo_new_path(ct);
- feed_curve_to_cairo (ct, shape->curve, NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0));
+ feed_curve_to_cairo (ct, SP_CURVE_BPATH(shape->curve), NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0));
cairo_stroke(ct);
cairo_new_path(ct);
- feed_curve_to_cairo (ct, shape->curve, NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0));
+ feed_curve_to_cairo (ct, SP_CURVE_BPATH(shape->curve), NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0));
cairo_fill(ct);