summaryrefslogtreecommitdiffstats
path: root/src/display/drawing-context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/display/drawing-context.cpp')
-rw-r--r--src/display/drawing-context.cpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/display/drawing-context.cpp b/src/display/drawing-context.cpp
new file mode 100644
index 0000000..75922d7
--- /dev/null
+++ b/src/display/drawing-context.cpp
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/**
+ * @file
+ * Cairo drawing context with Inkscape extensions.
+ *//*
+ * Authors:
+ * Krzysztof KosiƄski <tweenk.pl@gmail.com>
+ *
+ * Copyright (C) 2011 Authors
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include "display/drawing-context.h"
+#include "display/drawing-surface.h"
+#include "display/cairo-utils.h"
+
+namespace Inkscape {
+
+using Geom::X;
+using Geom::Y;
+
+/**
+ * @class DrawingContext::Save
+ * RAII idiom for saving the state of DrawingContext.
+ */
+
+DrawingContext::Save::Save()
+ : _dc(nullptr)
+{}
+DrawingContext::Save::Save(DrawingContext &dc)
+ : _dc(&dc)
+{
+ _dc->save();
+}
+DrawingContext::Save::~Save()
+{
+ if (_dc) {
+ _dc->restore();
+ }
+}
+void DrawingContext::Save::save(DrawingContext &dc)
+{
+ if (_dc) {
+ // TODO: it might be better to treat this occurrence as a bug
+ _dc->restore();
+ }
+ _dc = &dc;
+ _dc->save();
+}
+
+/**
+ * @class DrawingContext
+ * Minimal wrapper over Cairo.
+ *
+ * This is a wrapper over cairo_t, extended with operations that work
+ * with 2Geom geometrical primitives. Some of this is probably duplicated
+ * in cairo-render-context.cpp, which provides higher level operations
+ * for drawing entire SPObjects when exporting.
+ */
+
+// Uses existing Cairo surface
+DrawingContext::DrawingContext(cairo_t *ct, Geom::Point const &origin)
+ : _ct(ct)
+ , _surface(new DrawingSurface(cairo_get_group_target(ct), origin))
+ , _delete_surface(true)
+ , _restore_context(true)
+{
+ _surface->_has_context = true;
+ cairo_reference(_ct);
+ cairo_save(_ct);
+ cairo_translate(_ct, -origin[Geom::X], -origin[Geom::Y]);
+}
+
+// Uses existing Cairo surface
+DrawingContext::DrawingContext(cairo_surface_t *surface, Geom::Point const &origin)
+ : _ct(nullptr)
+ , _surface(new DrawingSurface(surface, origin))
+ , _delete_surface(true)
+ , _restore_context(false)
+{
+ _surface->_has_context = true;
+ _ct = _surface->createRawContext();
+}
+
+DrawingContext::DrawingContext(DrawingSurface &s)
+ : _ct(s.createRawContext())
+ , _surface(&s)
+ , _delete_surface(false)
+ , _restore_context(false)
+{}
+
+DrawingContext::~DrawingContext()
+{
+ if (_restore_context) {
+ cairo_restore(_ct);
+ }
+ cairo_destroy(_ct);
+ _surface->_has_context = false;
+ if (_delete_surface) {
+ delete _surface;
+ }
+}
+
+void DrawingContext::arc(Geom::Point const &center, double radius, Geom::AngleInterval const &angle)
+{
+ double from = angle.initialAngle();
+ double to = angle.finalAngle();
+ if (to > from) {
+ cairo_arc(_ct, center[X], center[Y], radius, from, to);
+ } else {
+ cairo_arc_negative(_ct, center[X], center[Y], radius, to, from);
+ }
+}
+
+// Applies transform to Cairo surface
+void DrawingContext::transform(Geom::Affine const &trans) {
+ ink_cairo_transform(_ct, trans);
+}
+
+void DrawingContext::path(Geom::PathVector const &pv) {
+ feed_pathvector_to_cairo(_ct, pv);
+}
+
+void DrawingContext::paint(double alpha) {
+ if (alpha == 1.0) cairo_paint(_ct);
+ else cairo_paint_with_alpha(_ct, alpha);
+}
+
+void DrawingContext::setHairline() {
+ ink_cairo_set_hairline(_ct);
+}
+
+void DrawingContext::setSource(guint32 rgba) {
+ ink_cairo_set_source_rgba32(_ct, rgba);
+}
+void DrawingContext::setSource(DrawingSurface *s) {
+ Geom::Point origin = s->origin();
+ cairo_set_source_surface(_ct, s->raw(), origin[X], origin[Y]);
+}
+void DrawingContext::setSourceCheckerboard() {
+ cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard();
+ cairo_set_source(_ct, check);
+ cairo_pattern_destroy(check);
+}
+
+Geom::Rect DrawingContext::targetLogicalBounds() const
+{
+ Geom::Rect ret(_surface->area());
+ return ret;
+}
+
+} // end namespace Inkscape
+
+/*
+ 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:fileencoding=utf-8:textwidth=99 :