summaryrefslogtreecommitdiffstats
path: root/src/display/inkscape-cairo.cpp
diff options
context:
space:
mode:
authorbulia byak <buliabyak@gmail.com>2007-03-01 04:15:17 +0000
committerbuliabyak <buliabyak@users.sourceforge.net>2007-03-01 04:15:17 +0000
commit86ab051d5b193a6e5434755a3fd94ce56fdbe000 (patch)
tree9266d0ab7bf60c2cef0f1c3e989438e153ea2ea0 /src/display/inkscape-cairo.cpp
parentFix massive point queueing and tolerance issue (diff)
downloadinkscape-86ab051d5b193a6e5434755a3fd94ce56fdbe000.tar.gz
inkscape-86ab051d5b193a6e5434755a3fd94ce56fdbe000.zip
render text in outline mode via cairo (still no endian-safe); factor out helper functions
(bzr r2470)
Diffstat (limited to 'src/display/inkscape-cairo.cpp')
-rw-r--r--src/display/inkscape-cairo.cpp108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/display/inkscape-cairo.cpp b/src/display/inkscape-cairo.cpp
new file mode 100644
index 000000000..39cd90ed6
--- /dev/null
+++ b/src/display/inkscape-cairo.cpp
@@ -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 :