Skip to content

Commit 8112cea

Browse files
committed
Update ReadSVG
Transforms seems to work ... Only tested on Ubuntu with the Natron logo. * #25 * NatronGitHub/Natron#970
1 parent 106aa7f commit 8112cea

File tree

3 files changed

+115
-151
lines changed

3 files changed

+115
-151
lines changed

Extra/ReadSVG.cpp

Lines changed: 76 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@
3434
#include "ofxsMultiPlane.h"
3535
#include "ofxsImageEffect.h"
3636

37-
// cairo helper functions
37+
// transform helper
38+
#include "ofxsTransform3x3.h"
39+
#include "ofxsTransformInteract.h"
40+
41+
// cairo helper
3842
#include "CairoHelper.h"
3943

4044
#define kPluginName "ReadSVG"
@@ -54,30 +58,10 @@
5458
#define kParamDpiHint "Dots-per-inch (90 is default)"
5559
#define kParamDpiDefault 90
5660

57-
#define kParamPivot "pivot"
58-
#define kParamPivotLabel "Pivot"
59-
#define kParamPivotHint "Apply origin on transform, else center of image."
60-
#define kParamPivotDefault false
61-
62-
#define kParamOrigin "origin"
63-
#define kParamOriginLabel "Origin"
64-
#define kParamOriginHint "Origin for transform."
65-
#define kParamOriginDefault 0.
66-
67-
#define kParamScale "scale"
68-
#define kParamScaleLabel "Scale"
69-
#define kParamScaleHint "Transform scale."
70-
#define kParamScaleDefault 1.
71-
72-
#define kParamSkew "skew"
73-
#define kParamSkewLabel "Skew"
74-
#define kParamSkewHint "Transform skew."
75-
#define kParamSkewDefault 0.
76-
77-
#define kParamRotate "rotate"
78-
#define kParamRotateLabel "Rotate"
79-
#define kParamRotateHint "Rotate the surface."
80-
#define kParamRotateDefault 0.
61+
#define kParamTranslateEnabled "translateEnabled"
62+
#define kParamTranslateEnabledLabel "Translate"
63+
#define kParamTranslateEnabledHint "Enable translate."
64+
#define kParamTranslateEnabledDefault false
8165

8266
#define kSupportsRGBA true
8367
#define kSupportsRGB false
@@ -179,12 +163,16 @@ class ReadSVGPlugin : public GenericReaderPlugin
179163
int *componentCount) OVERRIDE FINAL;
180164
virtual void changedFilename(const OFX::InstanceChangedArgs &args) OVERRIDE FINAL;
181165
void getLayers(xmlNode *node, std::vector<std::string> *layers);
182-
OFX::IntParam *_dpi;
183-
OFX::BooleanParam *_pivot;
184-
OFX::Double2DParam *_origin;
185-
OFX::Double2DParam *_scale;
186-
OFX::Double2DParam *_skew;
187-
OFX::DoubleParam *_rotate;
166+
IntParam *_dpi;
167+
BooleanParam *_translateEnabled;
168+
Double2DParam* _translate;
169+
DoubleParam* _rotate;
170+
Double2DParam* _scale;
171+
BooleanParam* _scaleUniform;
172+
DoubleParam* _skewX;
173+
DoubleParam* _skewY;
174+
ChoiceParam* _skewOrder;
175+
Double2DParam* _center;
188176
std::vector<std::string> imageLayers;
189177
};
190178

@@ -203,20 +191,29 @@ ReadSVGPlugin::ReadSVGPlugin(OfxImageEffectHandle handle,
203191
false
204192
#endif
205193
)
206-
,_dpi(nullptr)
207-
, _pivot(nullptr)
208-
, _origin(nullptr)
209-
, _scale(nullptr)
210-
, _skew(nullptr)
194+
, _dpi(nullptr)
195+
, _translateEnabled(nullptr)
196+
, _translate(nullptr)
211197
, _rotate(nullptr)
198+
, _scale(nullptr)
199+
, _scaleUniform(nullptr)
200+
, _skewX(nullptr)
201+
, _skewY(nullptr)
202+
, _skewOrder(nullptr)
203+
, _center(nullptr)
212204
{
213205
_dpi = fetchIntParam(kParamDpi);
214-
_pivot = fetchBooleanParam(kParamPivot);
215-
_origin = fetchDouble2DParam(kParamOrigin);
216-
_scale = fetchDouble2DParam(kParamScale);
217-
_skew = fetchDouble2DParam(kParamSkew);
218-
_rotate = fetchDoubleParam(kParamRotate);
219-
assert(_dpi && _pivot && _origin && _scale && _skew && _rotate);
206+
_translateEnabled = fetchBooleanParam(kParamTranslateEnabled);
207+
assert(_dpi && _translateEnabled);
208+
209+
_translate = fetchDouble2DParam(kParamTransformTranslateOld);
210+
_rotate = fetchDoubleParam(kParamTransformRotateOld);
211+
_scale = fetchDouble2DParam(kParamTransformScaleOld);
212+
_scaleUniform = fetchBooleanParam(kParamTransformScaleUniformOld);
213+
_skewX = fetchDoubleParam(kParamTransformSkewXOld);
214+
_skewY = fetchDoubleParam(kParamTransformSkewYOld);
215+
_skewOrder = fetchChoiceParam(kParamTransformSkewOrderOld);
216+
_center = fetchDouble2DParam(kParamTransformCenterOld);
220217
}
221218

222219
ReadSVGPlugin::~ReadSVGPlugin()
@@ -353,19 +350,22 @@ ReadSVGPlugin::decodePlane(const std::string& filename,
353350
cairo_surface_t *surface;
354351
cairo_t *cr;
355352
cairo_status_t status;
356-
double imageWidth, imageHeight, scaleWidth, scaleHeight, originX, originY, scaleX, scaleY, skewX, skewY, rotate;
357-
int dpi, width, height, renderWidth, renderHeight;
358-
bool pivot;
353+
double imageWidth, imageHeight, scaleWidth, scaleHeight;
354+
double translateX, translateY, rotate, scaleX, scaleY, skewX, skewY, centerX, centerY;
355+
int dpi, width, height, renderWidth, renderHeight, skewO;
356+
bool scaleUniform, translateEnabled;
359357

360358
_dpi->getValueAtTime(time, dpi);
361-
_pivot->getValueAtTime(time, pivot);
362-
_origin->getValueAtTime(time, originX, originY);
363-
_scale->getValueAtTime(time, scaleX, scaleY);
364-
_skew->getValueAtTime(time, skewX, skewY);
365-
_rotate->getValueAtTime(time, rotate);
359+
_translateEnabled->getValueAtTime(time, translateEnabled);
366360

367-
bool hasTransform = (pivot || scaleX != 1. || scaleY != 1. || skewX != 0. || skewY != 0. || rotate != 0.);
368-
bool hasDpi = (dpi != kParamDpiDefault);
361+
_translate->getValueAtTime(time, translateX, translateY);
362+
_rotate->getValueAtTime(time, rotate);
363+
_scale->getValueAtTime(time, scaleX, scaleY);
364+
_scaleUniform->getValueAtTime(time, scaleUniform);
365+
_skewX->getValueAtTime(time, skewX);
366+
_skewY->getValueAtTime(time, skewY);;
367+
_skewOrder->getValueAtTime(time, skewO);
368+
_center->getValueAtTime(time, centerX, centerY);
369369

370370
// load svg
371371
handle = rsvg_handle_new_from_file(filename.c_str(), &error);
@@ -384,15 +384,14 @@ ReadSVGPlugin::decodePlane(const std::string& filename,
384384
renderWidth= renderWindow.x2 - renderWindow.x1;
385385
renderHeight= renderWindow.y2 - renderWindow.y1;
386386

387-
if (hasDpi) {
387+
if (dpi != kParamDpiDefault) {
388388
width = imageWidth * dpi / kParamDpiDefault;
389389
height = imageHeight * dpi / kParamDpiDefault;
390390
}
391391
else {
392392
width = imageWidth;
393393
height = imageHeight;
394394
}
395-
396395
if (width != renderWidth || height != renderHeight) {
397396
setPersistentMessage(OFX::Message::eMessageError, "", "Image don't match RenderWindow");
398397
OFX::throwSuiteStatusException(kOfxStatErrFormat);
@@ -410,19 +409,14 @@ ReadSVGPlugin::decodePlane(const std::string& filename,
410409
CairoHelper::applyScale(cr, {scaleWidth, scaleHeight});
411410

412411
// transform
413-
if (hasTransform) {
414-
if (!pivot) {
415-
originX = hasDpi ? width / scaleWidth / 2. : width / 2.;
416-
originY = hasDpi ? height / scaleHeight / 2. : height / 2.;
417-
} else {
418-
// TODO
419-
}
420-
CairoHelper::applyTransform(cr, {{originX, originY},
421-
{scaleX, scaleY},
422-
{skewX, skewY},
423-
rotate,
424-
pivot});
425-
}
412+
CairoHelper::applyTransform(cr, {{translateX, translateY},
413+
{(translateEnabled ? translateX : centerX),
414+
(translateEnabled ? translateY : centerY)},
415+
{scaleX, scaleY},
416+
{(skewO == 1 ? skewY : skewX),
417+
(skewO == 1 ? skewX : skewY)},
418+
rotate,
419+
translateEnabled});
426420

427421
// render svg
428422
if (layerID.empty()) {
@@ -629,6 +623,9 @@ ReadSVGPluginFactory::describe(OFX::ImageEffectDescriptor &desc)
629623
kIsMultiPlanar);
630624
desc.setLabel(kPluginName);
631625
desc.setPluginDescription(kPluginDescription);
626+
627+
Transform3x3Describe(desc, true);
628+
desc.setOverlayInteractDescriptor(new TransformOverlayDescriptorOldParams);
632629
}
633630

634631
/** @brief The describe in context function, passed a plugin descriptor and a context */
@@ -655,67 +652,25 @@ ReadSVGPluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc,
655652
param->setDisplayRange(1, 500);
656653
param->setDefault(kParamDpiDefault);
657654
param->setAnimates(false);
658-
param->setLayoutHint(OFX::eLayoutHintDivider);
659-
if (page) { page->addChild(*param); }
660-
}
661-
{
662-
BooleanParamDescriptor* param = desc.defineBooleanParam(kParamPivot);
663-
param->setLabel(kParamPivotLabel);
664-
param->setHint(kParamPivotHint);
665-
param->setDefault(kParamPivotDefault);
666-
param->setAnimates(false);
667655
param->setLayoutHint(OFX::eLayoutHintNoNewLine);
668656
if (page) { page->addChild(*param); }
669657
}
670658
{
671-
Double2DParamDescriptor* param = desc.defineDouble2DParam(kParamOrigin);
672-
param->setLabel(kParamOriginLabel);
673-
param->setHint(kParamOriginHint);
674-
param->setRange(INT_MIN, INT_MIN,
675-
INT_MAX, INT_MAX);
676-
param->setDisplayRange(-1000, -1000,
677-
1000, 1000);
678-
param->setDefault(kParamOriginDefault,
679-
kParamOriginDefault);
680-
param->setAnimates(true);
681-
if (page) { page->addChild(*param); }
682-
}
683-
{
684-
Double2DParamDescriptor* param = desc.defineDouble2DParam(kParamScale);
685-
param->setLabel(kParamScaleLabel);
686-
param->setHint(kParamScaleHint);
687-
param->setRange(INT_MIN, INT_MIN,
688-
INT_MAX, INT_MAX);
689-
param->setDisplayRange(-5, -5,
690-
5, 5);
691-
param->setDefault(kParamScaleDefault,
692-
kParamScaleDefault);
693-
param->setAnimates(true);
694-
if (page) { page->addChild(*param); }
695-
}
696-
{
697-
Double2DParamDescriptor* param = desc.defineDouble2DParam(kParamSkew);
698-
param->setLabel(kParamSkewLabel);
699-
param->setHint(kParamSkewHint);
700-
param->setRange(INT_MIN, INT_MIN,
701-
INT_MAX, INT_MAX);
702-
param->setDisplayRange(-5, -5,
703-
5, 5);
704-
param->setDefault(kParamSkewDefault,
705-
kParamSkewDefault);
706-
param->setAnimates(true);
707-
if (page) { page->addChild(*param); }
708-
}
709-
{
710-
DoubleParamDescriptor* param = desc.defineDoubleParam(kParamRotate);
711-
param->setLabel(kParamRotateLabel);
712-
param->setHint(kParamRotateHint);
713-
param->setRange(-360., 360.);
714-
param->setDefault(kParamRotateDefault);
715-
param->setAnimates(true);
659+
BooleanParamDescriptor* param = desc.defineBooleanParam(kParamTranslateEnabled);
660+
param->setLabel(kParamTranslateEnabledLabel);
661+
param->setHint(kParamTranslateEnabledHint);
662+
param->setDefault(kParamTranslateEnabledDefault);
663+
param->setAnimates(false);
716664
param->setLayoutHint(OFX::eLayoutHintDivider);
717665
if (page) { page->addChild(*param); }
718666
}
667+
ofxsTransformDescribeParams(desc,
668+
page,
669+
NULL,
670+
true,
671+
true,
672+
false,
673+
false);
719674
GenericReaderDescribeInContextEnd(desc,
720675
context,
721676
page,

Helpers/CairoHelper.cpp

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,17 @@
2020

2121
#include <cmath>
2222

23-
void
24-
CairoHelper::applyFlip(cairo_t *cr,
25-
const int &height)
26-
{
27-
if (!cr || height < 1) { return; }
28-
cairo_scale(cr, 1.0f, -1.0f);
29-
cairo_translate(cr, 0.0f, -height);
30-
}
31-
3223
void
3324
CairoHelper::applyPosition(cairo_t *cr,
34-
const _XY &position)
25+
const _XY &position,
26+
const bool translate)
3527
{
3628
if (!cr) { return; }
37-
cairo_move_to(cr, position.x, position.y);
29+
if (translate) {
30+
cairo_translate(cr, position.x, position.y);
31+
} else {
32+
cairo_move_to(cr, position.x, position.y);
33+
}
3834
}
3935

4036
void
@@ -62,17 +58,23 @@ CairoHelper::applySkew(cairo_t *cr,
6258
const _XY &origin)
6359
{
6460
if (!cr || (skew.x == 0. && skew.y == 0.)) { return; }
65-
double x = skew.x;
66-
double y = skew.y;
67-
if (x != 0.) { x = -x; }
68-
if (y != 0.) { y = -y; }
69-
cairo_matrix_t matrix = {
70-
1.0, y,
71-
x , 1.0,
72-
0.0, 0.0
73-
};
7461
cairo_translate(cr, origin.x, origin.y);
75-
cairo_transform(cr, &matrix);
62+
if (skew.x != 0.) {
63+
cairo_matrix_t matrix = {
64+
1.0, 0.0,
65+
skew.x, 1.0,
66+
0.0, 0.0
67+
};
68+
cairo_transform(cr, &matrix);
69+
}
70+
if (skew.y != 0.) {
71+
cairo_matrix_t matrix = {
72+
1.0, skew.y,
73+
0.0, 1.0,
74+
0.0, 0.0
75+
};
76+
cairo_transform(cr, &matrix);
77+
}
7678
cairo_translate(cr, -origin.x, -origin.y);
7779
}
7880

@@ -83,7 +85,7 @@ CairoHelper::applyRotate(cairo_t *cr,
8385
{
8486
if (!cr || rotate == 0.) { return; }
8587
cairo_translate(cr, origin.x, origin.y);
86-
cairo_rotate(cr, -rotate * (M_PI / 180.0));
88+
cairo_rotate(cr, rotate * (M_PI / 180.0));
8789
cairo_translate(cr, -origin.x, -origin.y);
8890
}
8991

@@ -92,8 +94,16 @@ CairoHelper::applyTransform(cairo_t *cr,
9294
const _Transform &transform)
9395
{
9496
if (!cr) { return; }
95-
if (transform.position) { applyPosition(cr, transform.origin); }
96-
applyScale(cr, transform.scale, transform.origin);
97-
applySkew(cr, transform.skew, transform.origin);
98-
applyRotate(cr, transform.rotate, transform.origin);
97+
if (transform.position) { applyPosition(cr,
98+
transform.translate,
99+
true); }
100+
applyScale(cr,
101+
transform.scale,
102+
transform.origin);
103+
applySkew(cr,
104+
transform.skew,
105+
transform.origin);
106+
applyRotate(cr,
107+
transform.rotate,
108+
transform.origin);
99109
}

Helpers/CairoHelper.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,17 @@ class CairoHelper
3131
};
3232
struct _Transform
3333
{
34+
_XY translate;
3435
_XY origin;
3536
_XY scale;
3637
_XY skew;
3738
double rotate;
3839
bool position;
3940
};
40-
/** @brief apply flip */
41-
static void applyFlip(cairo_t *cr,
42-
const int &height);
4341
/** @brief apply position */
4442
static void applyPosition(cairo_t *cr,
45-
const _XY &position);
43+
const _XY &position,
44+
const bool translate = false);
4645
/** @brief apply scale */
4746
static void applyScale(cairo_t *cr,
4847
const _XY &scale);

0 commit comments

Comments
 (0)