diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2016-02-08 07:32:51 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2016-02-08 07:32:51 +0000 |
| commit | 0a2477feea6e1df586b926b8482afbf79e2355e1 (patch) | |
| tree | 109bce789702f504ab3bc90e2fe4541b421b0940 /src/2geom/rect.cpp | |
| parent | Changed one icon/action in meassure toolbar to one more explicit (diff) | |
| download | inkscape-0a2477feea6e1df586b926b8482afbf79e2355e1.tar.gz inkscape-0a2477feea6e1df586b926b8482afbf79e2355e1.zip | |
Sync 2Geom to commit 5ee51c1c4f2066faa3e2c82021fc92671ad44ba4
(bzr r14639)
Diffstat (limited to 'src/2geom/rect.cpp')
| -rw-r--r-- | src/2geom/rect.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/2geom/rect.cpp b/src/2geom/rect.cpp index 383e72c8e..5a821e9f9 100644 --- a/src/2geom/rect.cpp +++ b/src/2geom/rect.cpp @@ -30,9 +30,56 @@ */ #include <2geom/rect.h> +#include <2geom/transforms.h> namespace Geom { +Point align_factors(Align g) { + Point p; + switch (g) { + case ALIGN_XMIN_YMIN: + p[X] = 0.0; + p[Y] = 0.0; + break; + case ALIGN_XMID_YMIN: + p[X] = 0.5; + p[Y] = 0.0; + break; + case ALIGN_XMAX_YMIN: + p[X] = 1.0; + p[Y] = 0.0; + break; + case ALIGN_XMIN_YMID: + p[X] = 0.0; + p[Y] = 0.5; + break; + case ALIGN_XMID_YMID: + p[X] = 0.5; + p[Y] = 0.5; + break; + case ALIGN_XMAX_YMID: + p[X] = 1.0; + p[Y] = 0.5; + break; + case ALIGN_XMIN_YMAX: + p[X] = 0.0; + p[Y] = 1.0; + break; + case ALIGN_XMID_YMAX: + p[X] = 0.5; + p[Y] = 1.0; + break; + case ALIGN_XMAX_YMAX: + p[X] = 1.0; + p[Y] = 1.0; + break; + default: + break; + } + return p; +} + + /** @brief Transform the rectangle by an affine. * The result of the transformation might not be axis-aligned. The return value * of this operation will be the smallest axis-aligned rectangle containing @@ -49,6 +96,37 @@ Rect &Rect::operator*=(Affine const &m) { return *this; } +Affine Rect::transformTo(Rect const &viewport, Aspect const &aspect) const +{ + // 1. translate viewbox to origin + Geom::Affine total = Translate(-min()); + + // 2. compute scale + Geom::Point vdims = viewport.dimensions(); + Geom::Point dims = dimensions(); + Geom::Scale scale(vdims[X] / dims[X], vdims[Y] / dims[Y]); + + if (aspect.align == ALIGN_NONE) { + // apply non-uniform scale + total *= scale * Translate(viewport.min()); + } else { + double uscale = 0; + if (aspect.expansion == EXPANSION_MEET) { + uscale = std::min(scale[X], scale[Y]); + } else { + uscale = std::max(scale[X], scale[Y]); + } + scale = Scale(uscale); + + // compute offset for align + Geom::Point offset = vdims - dims * scale; + offset *= Scale(align_factors(aspect.align)); + total *= scale * Translate(viewport.min() + offset); + } + + return total; +} + Coord distanceSq(Point const &p, Rect const &rect) { double dx = 0, dy = 0; |
