895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free/*
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * viewBox helper class, common code used by root, symbol, marker, pattern, image, view
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free *
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Authors:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Lauris Kaplinski <lauris@kaplinski.com> (code extracted from symbol.cpp)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Tavmjong Bah <tavmjong@free.fr>
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen * Johan Engelen
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free *
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen * Copyright (C) 2013-2014 Tavmjong Bah, authors
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free *
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Released under GNU GPL, read the file 'COPYING' for more information
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free *
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#include <2geom/transforms.h>
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#include "viewbox.h"
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#include "attributes.h"
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#include "enums.h"
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free#include "sp-item.h"
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. EngelenSPViewBox::SPViewBox()
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen : viewBox_set(false)
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen , viewBox()
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen , aspect_set(false)
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen , aspect_align(SP_ASPECT_XMID_YMID) // Default per spec
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen , aspect_clip(SP_ASPECT_MEET)
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen , c2p(Geom::identity())
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen{
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free}
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freevoid SPViewBox::set_viewBox(const gchar* value) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if (value) {
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen gchar *eptr = const_cast<gchar*>(value); // const-cast necessary because of const-incorrect interface definition of g_ascii_strtod
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen double x = g_ascii_strtod (eptr, &eptr);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free eptr++;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen double y = g_ascii_strtod (eptr, &eptr);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free eptr++;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen double width = g_ascii_strtod (eptr, &eptr);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free eptr++;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen double height = g_ascii_strtod (eptr, &eptr);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free eptr++;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if ((width > 0) && (height > 0)) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Set viewbox */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->viewBox = Geom::Rect::from_xywh(x, y, width, height);
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen this->viewBox_set = true;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else {
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen this->viewBox_set = false;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else {
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen this->viewBox_set = false;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen // The C++ way? -- not necessarily using iostreams
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // std::string sv( value );
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // std::replace( sv.begin(), sv.end(), ',', ' ');
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // std::stringstream ss( sv );
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // double x, y, width, height;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // ss >> x >> y >> width >> height;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free}
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freevoid SPViewBox::set_preserveAspectRatio(const gchar* value) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Do setup before, so we can use break to escape */
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen this->aspect_set = false;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->aspect_align = SP_ASPECT_XMID_YMID; // Default per spec
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->aspect_clip = SP_ASPECT_MEET;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if (value) {
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen const gchar *p = value;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen while (*p && (*p == 32)) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free p += 1;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if (!*p) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free return;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen const gchar *e = p;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen while (*e && (*e != 32)) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free e += 1;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen int len = e - p;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
dca8db2be67c87ad222c2c58cca33d3e57f1b650tavmjong-free if (len > 8) { // Can't have buffer overflow as 8 < 256
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free return;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen gchar c[256];
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free memcpy (c, value, len);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free c[len] = 0;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Now the actual part */
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen unsigned int align = SP_ASPECT_NONE;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if (!strcmp (c, "none")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free align = SP_ASPECT_NONE;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else if (!strcmp (c, "xMinYMin")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free align = SP_ASPECT_XMIN_YMIN;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else if (!strcmp (c, "xMidYMin")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free align = SP_ASPECT_XMID_YMIN;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else if (!strcmp (c, "xMaxYMin")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free align = SP_ASPECT_XMAX_YMIN;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else if (!strcmp (c, "xMinYMid")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free align = SP_ASPECT_XMIN_YMID;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else if (!strcmp (c, "xMidYMid")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free align = SP_ASPECT_XMID_YMID;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else if (!strcmp (c, "xMaxYMid")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free align = SP_ASPECT_XMAX_YMID;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else if (!strcmp (c, "xMinYMax")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free align = SP_ASPECT_XMIN_YMAX;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else if (!strcmp (c, "xMidYMax")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free align = SP_ASPECT_XMID_YMAX;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else if (!strcmp (c, "xMaxYMax")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free align = SP_ASPECT_XMAX_YMAX;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free return;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen unsigned int clip = SP_ASPECT_MEET;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen while (*e && (*e == 32)) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free e += 1;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if (*e) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if (!strcmp (e, "meet")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free clip = SP_ASPECT_MEET;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else if (!strcmp (e, "slice")) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free clip = SP_ASPECT_SLICE;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free } else {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free return;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen this->aspect_set = true;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->aspect_align = align;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->aspect_clip = clip;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free}
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free// Apply scaling from viewbox
71c8c050ee018790e1eb72748f193b1d25dab706apennervoid SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Determine actual viewbox in viewport coordinates */
71c8c050ee018790e1eb72748f193b1d25dab706apenner // scale_none is the scale that would apply if the viewbox and page size are same size
71c8c050ee018790e1eb72748f193b1d25dab706apenner // it is passed here because it is a double-precision variable, while 'in' is originally float
81efba162b1fc851b6bf0a5ca33928c37effa779apenner double x = 0.0;
81efba162b1fc851b6bf0a5ca33928c37effa779apenner double y = 0.0;
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner double scale_x = in.width() / this->viewBox.width();
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner double scale_y = in.height() / this->viewBox.height();
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner double scale_uniform = 1.0; // used only if scaling is uniform
81efba162b1fc851b6bf0a5ca33928c37effa779apenner
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner if (Geom::are_near(scale_x / scale_y, 1.0, Geom::EPSILON)) {
81efba162b1fc851b6bf0a5ca33928c37effa779apenner // scaling is already uniform, reduce numerical error
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner scale_uniform = (scale_x + scale_y)/2.0;
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner if (Geom::are_near(scale_uniform / scale_none, 1.0, Geom::EPSILON))
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner scale_uniform = scale_none; // objects are same size, reduce numerical error
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner scale_x = scale_uniform;
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner scale_y = scale_uniform;
81efba162b1fc851b6bf0a5ca33928c37effa779apenner } else if (this->aspect_align != SP_ASPECT_NONE) {
81efba162b1fc851b6bf0a5ca33928c37effa779apenner // scaling is not uniform, but force it to be
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner scale_uniform = (this->aspect_clip == SP_ASPECT_MEET) ? MIN (scale_x, scale_y) : MAX (scale_x, scale_y);
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner scale_x = scale_uniform;
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner scale_y = scale_uniform;
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner double width = this->viewBox.width() * scale_uniform;
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner double height = this->viewBox.height() * scale_uniform;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Now place viewbox to requested position */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free switch (this->aspect_align) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free case SP_ASPECT_XMIN_YMIN:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free break;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free case SP_ASPECT_XMID_YMIN:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free x = 0.5 * (in.width() - width);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free break;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free case SP_ASPECT_XMAX_YMIN:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free x = 1.0 * (in.width() - width);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free break;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free case SP_ASPECT_XMIN_YMID:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free y = 0.5 * (in.height() - height);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free break;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free case SP_ASPECT_XMID_YMID:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free x = 0.5 * (in.width() - width);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free y = 0.5 * (in.height() - height);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free break;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free case SP_ASPECT_XMAX_YMID:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free x = 1.0 * (in.width() - width);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free y = 0.5 * (in.height() - height);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free break;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free case SP_ASPECT_XMIN_YMAX:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free y = 1.0 * (in.height() - height);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free break;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free case SP_ASPECT_XMID_YMAX:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free x = 0.5 * (in.width() - width);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free y = 1.0 * (in.height() - height);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free break;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free case SP_ASPECT_XMAX_YMAX:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free x = 1.0 * (in.width() - width);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free y = 1.0 * (in.height() - height);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free break;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free default:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free break;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Viewbox transform from scale and position */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free Geom::Affine q;
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner q[0] = scale_x;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free q[1] = 0.0;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free q[2] = 0.0;
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner q[3] = scale_y;
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner q[4] = x - scale_x * this->viewBox.left();
0ff02b3688fe274104311bd443e7c5eee89d92e9apenner q[5] = y - scale_y * this->viewBox.top();
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // std::cout << " q\n" << q << std::endl;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Append viewbox transformation */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->c2p = q * this->c2p;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free}
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
71c8c050ee018790e1eb72748f193b1d25dab706apennerSPItemCtx SPViewBox::get_rctx(const SPItemCtx* ictx, double scale_none) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Create copy of item context */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free SPItemCtx rctx = *ictx;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Calculate child to parent transformation */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Apply parent translation (set up as viewport) */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free this->c2p = Geom::Translate(rctx.viewport.min());
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if (this->viewBox_set) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free // Adjusts c2p for viewbox
71c8c050ee018790e1eb72748f193b1d25dab706apenner apply_viewbox( rctx.viewport, scale_none );
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free rctx.i2doc = this->c2p * rctx.i2doc;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* If viewBox is set initialize child viewport */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free /* Otherwise it is already correct */
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if (this->viewBox_set) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free rctx.viewport = this->viewBox;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free rctx.i2vp = Geom::identity();
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free }
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free return rctx;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free}
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free/*
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free Local Variables:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free mode:c++
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free c-file-style:"stroustrup"
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free c-basic-offset:2
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free indent-tabs-mode:nil
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free fill-column:99
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free End:
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free*/
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free// vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=8:softtabstop=2:fileencoding=utf-8:textwidth=99 :