From f7b4cc602b9a646fbc66f3f17d6bb9c20efc3ead Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 24 Jan 2021 18:44:56 +0100 Subject: Initial commit --- .../clipper-6.4.2/cpp/cpp_cairo/cairo_clipper.cpp | 133 +++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 upstream/clipper-6.4.2/cpp/cpp_cairo/cairo_clipper.cpp (limited to 'upstream/clipper-6.4.2/cpp/cpp_cairo/cairo_clipper.cpp') diff --git a/upstream/clipper-6.4.2/cpp/cpp_cairo/cairo_clipper.cpp b/upstream/clipper-6.4.2/cpp/cpp_cairo/cairo_clipper.cpp new file mode 100644 index 0000000..72d5930 --- /dev/null +++ b/upstream/clipper-6.4.2/cpp/cpp_cairo/cairo_clipper.cpp @@ -0,0 +1,133 @@ +/******************************************************************************* +* * +* Author : Angus Johnson * +* Version : 1.1 * +* Date : 4 April 2011 * +* Copyright : Angus Johnson 2010-2011 * +* * +* License: * +* Use, modification & distribution is subject to Boost Software License Ver 1. * +* http://www.boost.org/LICENSE_1_0.txt * +* * +* Modified by Mike Owens to support coordinate transformation * +*******************************************************************************/ + +#include +#include +#include +#include +#include "clipper.hpp" +#include "cairo_clipper.hpp" + +namespace ClipperLib { + namespace cairo { + + namespace { + + inline cInt Round(double val) + { + if ((val < 0)) return (cInt)(val - 0.5); else return (cInt)(val + 0.5); + } + + void transform_point(cairo_t* pen, Transform transform, cInt* x, cInt* y) + { + double _x = (double)*x, _y = (double)*y; + switch (transform) + { + case tDeviceToUser: + cairo_device_to_user(pen, &_x, &_y); + break; + case tUserToDevice: + cairo_user_to_device(pen, &_x, &_y); + break; + default: + ; + } + *x = Round(_x); *y = Round(_y); + } + } + + void cairo_to_clipper(cairo_t* cr, + Paths &pg, + int scaling_factor, + Transform transform) + { + if (scaling_factor > 8 || scaling_factor < 0) + throw clipperCairoException("cairo_to_clipper: invalid scaling factor"); + double scaling = std::pow((double)10, scaling_factor); + + pg.clear(); + cairo_path_t *path = cairo_copy_path_flat(cr); + + int poly_count = 0; + for (int i = 0; i < path->num_data; i += path->data[i].header.length) { + if( path->data[i].header.type == CAIRO_PATH_CLOSE_PATH) poly_count++; + } + + pg.resize(poly_count); + int i = 0, pc = 0; + while (pc < poly_count) + { + int vert_count = 1; + int j = i; + while(j < path->num_data && path->data[j].header.type != CAIRO_PATH_CLOSE_PATH) + { + if (path->data[j].header.type == CAIRO_PATH_LINE_TO) + vert_count++; + j += path->data[j].header.length; + } + pg[pc].resize(vert_count); + if (path->data[i].header.type != CAIRO_PATH_MOVE_TO) { + pg.resize(pc); + break; + } + pg[pc][0].X = Round(path->data[i+1].point.x *scaling); + pg[pc][0].Y = Round(path->data[i+1].point.y *scaling); + if (transform != tNone) + transform_point(cr, transform, &pg[pc][0].X, &pg[pc][0].Y); + + i += path->data[i].header.length; + + j = 1; + while (j < vert_count && i < path->num_data && path->data[i].header.type == CAIRO_PATH_LINE_TO) { + pg[pc][j].X = Round(path->data[i+1].point.x *scaling); + pg[pc][j].Y = Round(path->data[i+1].point.y *scaling); + if (transform != tNone) + transform_point(cr, transform, &pg[pc][j].X, &pg[pc][j].Y); + j++; + i += path->data[i].header.length; + } + pc++; + i += path->data[i].header.length; + } + cairo_path_destroy(path); + } + //-------------------------------------------------------------------------- + + void clipper_to_cairo(const Paths &pg, cairo_t* cr, int scaling_factor, Transform transform) + { + if (scaling_factor > 8 || scaling_factor < 0) + throw clipperCairoException("clipper_to_cairo: invalid scaling factor"); + double scaling = std::pow((double)10, scaling_factor); + for (size_t i = 0; i < pg.size(); ++i) + { + size_t sz = pg[i].size(); + if (sz < 3) + continue; + cairo_new_sub_path(cr); + //std::cerr << "sub path"; + for (size_t j = 0; j < sz; ++j) { + cInt x = pg[i][j].X, y = pg[i][j].Y; + if (transform != tNone) + transform_point(cr, transform, &x, &y); + //std::cerr << " (" << (double)x / scaling << "," << (double)y / scaling << ")"; + cairo_line_to(cr, (double)x / scaling, (double)y / scaling); + } + //std::cerr << std::endl; + cairo_close_path(cr); + } + } + //-------------------------------------------------------------------------- + + } +} -- cgit