summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-10-15 23:20:12 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-10-15 23:20:12 +0000
commit36fc3ed3c81a7828ae961a793adaf630d571f9b7 (patch)
treecf0c89fdc713f96eba2f760b909c0c648eb075b4 /src
parentupdate to trunk (diff)
parentBug fixes in roughen and added uption to retract handles (diff)
downloadinkscape-36fc3ed3c81a7828ae961a793adaf630d571f9b7.tar.gz
inkscape-36fc3ed3c81a7828ae961a793adaf630d571f9b7.zip
update to trunk
(bzr r14393.1.21)
Diffstat (limited to 'src')
-rw-r--r--src/2geom/path-sink.cpp4
-rw-r--r--src/attributes-test.h3
-rw-r--r--src/attributes.cpp2
-rw-r--r--src/attributes.h2
-rw-r--r--src/libnrtype/Layout-TNG-Input.cpp36
-rw-r--r--src/live_effects/lpe-roughen.cpp256
-rw-r--r--src/live_effects/lpe-roughen.h11
-rw-r--r--src/object-snapper.cpp43
-rw-r--r--src/pure-transform.cpp2
-rw-r--r--src/style-enums.h39
-rw-r--r--src/style.cpp27
-rw-r--r--src/style.h8
-rw-r--r--src/uri-references.cpp158
-rw-r--r--src/widgets/gradient-vector.cpp3
14 files changed, 338 insertions, 256 deletions
diff --git a/src/2geom/path-sink.cpp b/src/2geom/path-sink.cpp
index 3b8d407f8..77301b716 100644
--- a/src/2geom/path-sink.cpp
+++ b/src/2geom/path-sink.cpp
@@ -73,8 +73,8 @@ void PathSink::feed(Rect const &r) {
void PathSink::feed(Circle const &e) {
Coord r = e.radius();
Point c = e.center();
- Point a = c + Point(0, c[Y] + r);
- Point b = c + Point(0, c[Y] - r);
+ Point a = c + Point(0, +r);
+ Point b = c + Point(0, -r);
moveTo(a);
arcTo(r, r, 0, false, false, b);
diff --git a/src/attributes-test.h b/src/attributes-test.h
index 411304ec3..e197deedf 100644
--- a/src/attributes-test.h
+++ b/src/attributes-test.h
@@ -43,6 +43,7 @@ public:
SVG 2: text-decoration-fill, text-decoration-stroke
SVG 2: solid-color, solid-opacity
SVG 2: Hatches and Meshes
+ CSS 3: text-orientation
CSS 3: font-variant-xxx, font-feature-settings
*/
struct {char const *attr; bool supported;} const all_attrs[] = {
@@ -69,7 +70,6 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"baseProfile", false},
{"bbox", true},
{"bias", true},
- {"block-progression", true},
{"by", true},
{"calcMode", true},
{"cap-height", true},
@@ -334,6 +334,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"widths", true},
{"word-spacing", true},
{"writing-mode", true},
+ {"text-orientation", true},
{"x", true},
{"x-height", true},
{"x1", true},
diff --git a/src/attributes.cpp b/src/attributes.cpp
index 991834cb2..a237f8861 100644
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
@@ -440,8 +440,8 @@ static SPStyleProp const props[] = {
/* Text (css3) */
{SP_PROP_DIRECTION, "direction"},
- {SP_PROP_BLOCK_PROGRESSION, "block-progression"},
{SP_PROP_WRITING_MODE, "writing-mode"},
+ {SP_PROP_TEXT_ORIENTATION, "text-orientation"},
{SP_PROP_UNICODE_BIDI, "unicode-bidi"},
{SP_PROP_ALIGNMENT_BASELINE, "alignment-baseline"},
{SP_PROP_BASELINE_SHIFT, "baseline-shift"},
diff --git a/src/attributes.h b/src/attributes.h
index 47f1388b0..42ec99d8f 100644
--- a/src/attributes.h
+++ b/src/attributes.h
@@ -444,8 +444,8 @@ enum SPAttributeEnum {
SP_PROP_TEXT_TRANSFORM,
SP_PROP_DIRECTION,
- SP_PROP_BLOCK_PROGRESSION,
SP_PROP_WRITING_MODE,
+ SP_PROP_TEXT_ORIENTATION,
SP_PROP_UNICODE_BIDI,
SP_PROP_ALIGNMENT_BASELINE,
SP_PROP_BASELINE_SHIFT,
diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp
index c9cfe81cc..77480cebe 100644
--- a/src/libnrtype/Layout-TNG-Input.cpp
+++ b/src/libnrtype/Layout-TNG-Input.cpp
@@ -172,34 +172,24 @@ float Layout::InputStreamTextSource::styleComputeFontSize() const
return medium_font_size * inherit_multiplier;
}
-static const Layout::EnumConversionItem enum_convert_spstyle_block_progression_to_direction[] = {
- {SP_CSS_BLOCK_PROGRESSION_TB, Layout::TOP_TO_BOTTOM},
- {SP_CSS_BLOCK_PROGRESSION_LR, Layout::LEFT_TO_RIGHT},
- {SP_CSS_BLOCK_PROGRESSION_RL, Layout::RIGHT_TO_LEFT}};
-
-static const Layout::EnumConversionItem enum_convert_spstyle_writing_mode_to_direction[] = {
- {SP_CSS_WRITING_MODE_LR_TB, Layout::TOP_TO_BOTTOM},
- {SP_CSS_WRITING_MODE_RL_TB, Layout::TOP_TO_BOTTOM},
- {SP_CSS_WRITING_MODE_TB_RL, Layout::RIGHT_TO_LEFT},
- {SP_CSS_WRITING_MODE_TB_LR, Layout::LEFT_TO_RIGHT}};
-
Layout::Direction Layout::InputStreamTextSource::styleGetBlockProgression() const
{
- // this function shouldn't be necessary, but since style.cpp doesn't support
- // shorthand properties yet, it is.
- SPStyle const *this_style = style;
+ switch( style->writing_mode.computed ) {
- for ( ; ; ) {
- if (this_style->block_progression.set)
- return (Layout::Direction)_enum_converter(this_style->block_progression.computed, enum_convert_spstyle_block_progression_to_direction, sizeof(enum_convert_spstyle_block_progression_to_direction)/sizeof(enum_convert_spstyle_block_progression_to_direction[0]));
- if (this_style->writing_mode.set)
- return (Layout::Direction)_enum_converter(this_style->writing_mode.computed, enum_convert_spstyle_writing_mode_to_direction, sizeof(enum_convert_spstyle_writing_mode_to_direction)/sizeof(enum_convert_spstyle_writing_mode_to_direction[0]));
- if (this_style->object == NULL || this_style->object->parent == NULL) break;
- this_style = this_style->object->parent->style;
- if (this_style == NULL) break;
- }
+ case SP_CSS_WRITING_MODE_LR_TB:
+ case SP_CSS_WRITING_MODE_RL_TB:
return TOP_TO_BOTTOM;
+
+ case SP_CSS_WRITING_MODE_TB_RL:
+ return RIGHT_TO_LEFT;
+
+ case SP_CSS_WRITING_MODE_TB_LR:
+ return LEFT_TO_RIGHT;
+ default:
+ std::cerr << "Layout::InputTextStream::styleGetBlockProgression: invalid writing mode." << std::endl;
+ }
+ return TOP_TO_BOTTOM;
}
static Layout::Alignment text_anchor_to_alignment(unsigned anchor, Layout::Direction para_direction)
diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp
index 33ffd96d6..ed1ddcaf8 100644
--- a/src/live_effects/lpe-roughen.cpp
+++ b/src/live_effects/lpe-roughen.cpp
@@ -49,8 +49,14 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject)
"global_randomize", &wr, this, 1.),
shift_nodes(_("Shift nodes"), _("Shift nodes"), "shift_nodes", &wr, this,
true),
- shift_node_handles(_("Shift node handles"), _("Shift node handles"),
- "shift_node_handles", &wr, this, true)
+ shift_handles(_("Shift node handles"), _("Shift node handles"),
+ "shift_handles", &wr, this, true),
+ retract_handles(_("Retract node handles"), _("Retract node handles"),
+ "retract_handles", &wr, this, false),
+ shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"),
+ "shift_handles_sym", &wr, this, false),
+ fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment lenght"),
+ "fixed_displacement", &wr, this, false)
{
registerParameter(&method);
registerParameter(&max_segment_size);
@@ -59,7 +65,10 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject)
registerParameter(&displace_y);
registerParameter(&global_randomize);
registerParameter(&shift_nodes);
- registerParameter(&shift_node_handles);
+ registerParameter(&shift_handles);
+ registerParameter(&retract_handles);
+ registerParameter(&shift_handles_sym);
+ registerParameter(&fixed_displacement);
displace_x.param_set_range(0., Geom::infinity());
displace_y.param_set_range(0., Geom::infinity());
global_randomize.param_set_range(0., Geom::infinity());
@@ -147,19 +156,21 @@ double LPERoughen::sign(double random_number)
return random_number;
}
-Geom::Point LPERoughen::randomize()
+Geom::Point LPERoughen::randomize(double max_lenght)
{
double displace_x_parsed = displace_x * global_randomize;
double displace_y_parsed = displace_y * global_randomize;
-
Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed));
+ if( fixed_displacement ){
+ Geom::Ray ray(Geom::Point(0,0),output);
+ output = Geom::Point::polar(ray.angle(), max_lenght);
+ }
return output;
}
void LPERoughen::doEffect(SPCurve *curve)
{
- Geom::PathVector const original_pathv =
- pathv_to_linear_and_cubic_beziers(curve->get_pathvector());
+ Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector());
curve->reset();
for (Geom::PathVector::const_iterator path_it = original_pathv.begin();
path_it != original_pathv.end(); ++path_it) {
@@ -170,40 +181,15 @@ void LPERoughen::doEffect(SPCurve *curve)
Geom::Path::const_iterator curve_it2 = ++(path_it->begin());
Geom::Path::const_iterator curve_endit = path_it->end_default();
SPCurve *nCurve = new SPCurve();
- if (path_it->closed()) {
- const Geom::Curve &closingline =
- path_it->back_closed();
- if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
- curve_endit = path_it->end_open();
- }
- }
- Geom::Point initialMove(0, 0);
- if (shift_nodes) {
- initialMove = randomize();
- }
- Geom::Point initialPoint = curve_it1->initialPoint() + initialMove;
- nCurve->moveto(initialPoint);
- Geom::Point point0(0, 0);
- Geom::Point point1(0, 0);
- Geom::Point point2(0, 0);
- Geom::Point point3(0, 0);
- bool first = true;
+ Geom::Point prev(0, 0);
+ nCurve->moveto(curve_it1->initialPoint());
while (curve_it1 != curve_endit) {
Geom::CubicBezier const *cubic = NULL;
- point0 = curve_it1->initialPoint();
- point1 = curve_it1->initialPoint();
- point2 = curve_it1->finalPoint();
- point3 = curve_it1->finalPoint();
cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
if (cubic) {
- point1 = (*cubic)[1];
- if (shift_nodes && first) {
- point1 = (*cubic)[1] + initialMove;
- }
- point2 = (*cubic)[2];
- nCurve->curveto(point1, point2, point3);
+ nCurve->curveto((*cubic)[1], (*cubic)[2], curve_it1->finalPoint());
} else {
- nCurve->lineto(point3);
+ nCurve->lineto(curve_it1->finalPoint());
}
double length = curve_it1->length(0.001);
std::size_t splits = 0;
@@ -212,15 +198,21 @@ void LPERoughen::doEffect(SPCurve *curve)
} else {
splits = ceil(length / max_segment_size);
}
- for (unsigned int t = splits; t >= 1; t--) {
- if (t == 1 && splits != 1) {
+ Geom::Curve const * original = nCurve->last_segment()->duplicate() ;
+ for (unsigned int t = 1; t <= splits; t++) {
+ if(t == splits && splits != 1){
continue;
}
- const SPCurve *tmp;
+ SPCurve const * tmp;
if (splits == 1) {
- tmp = jitter(nCurve->last_segment());
+ tmp = jitter(nCurve->last_segment(), prev);
} else {
- tmp = addNodesAndJitter(nCurve->last_segment(), 1. / t);
+ bool last = false;
+ if(t == splits-1){
+ last = true;
+ }
+ double time = Geom::nearest_time(original->pointAt((1. / (double)splits) * t), *nCurve->last_segment());
+ tmp = addNodesAndJitter(nCurve->last_segment(), prev, time, last);
}
if (nCurve->get_segment_count() > 1) {
nCurve->backspace();
@@ -231,12 +223,32 @@ void LPERoughen::doEffect(SPCurve *curve)
delete tmp;
}
++curve_it1;
- if(curve_it2 != curve_endit) {
- ++curve_it2;
- }
- first = false;
+ ++curve_it2;
}
if (path_it->closed()) {
+ if(shift_handles_sym && curve_it1 == curve_endit && !retract_handles){
+ SPCurve *out = new SPCurve();
+ nCurve = nCurve->create_reverse();
+ Geom::CubicBezier const *cubic_start = dynamic_cast<Geom::CubicBezier const *>(nCurve->first_segment());
+ Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(nCurve->last_segment());
+ Geom::Point oposite = nCurve->first_segment()->pointAt(1.0/3.0);
+ if(cubic_start){
+ Geom::Ray ray((*cubic_start)[1], (*cubic_start)[0]);
+ double dist = Geom::distance((*cubic_start)[1], (*cubic_start)[0]);
+ oposite = Geom::Point::polar(ray.angle(),dist) + (*cubic_start)[0];
+ }
+ if(cubic){
+ out->moveto((*cubic)[0]);
+ out->curveto((*cubic)[1], oposite, (*cubic)[3]);
+ } else {
+ out->moveto(nCurve->last_segment()->initialPoint());
+ out->curveto(nCurve->last_segment()->initialPoint(), oposite, nCurve->last_segment()->finalPoint());
+ }
+ nCurve->backspace();
+ nCurve->append_continuous(out, 0.001);
+ nCurve = nCurve->create_reverse();
+ }
+ nCurve->move_endpoints(nCurve->last_segment()->finalPoint(), nCurve->last_segment()->finalPoint());
nCurve->closepath_current();
}
curve->append(nCurve, false);
@@ -245,77 +257,151 @@ void LPERoughen::doEffect(SPCurve *curve)
}
}
-SPCurve *LPERoughen::addNodesAndJitter(const Geom::Curve *A, double t)
+SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last)
{
SPCurve *out = new SPCurve();
Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*A);
- Geom::Point point1(0, 0);
- Geom::Point point2(0, 0);
- Geom::Point point3(0, 0);
+ double max_lenght = Geom::distance(A->initialPoint(),A->pointAt(t)) / 3.0;
+ Geom::Point point_a1(0, 0);
+ Geom::Point point_a2(0, 0);
+ Geom::Point point_a3(0, 0);
Geom::Point point_b1(0, 0);
Geom::Point point_b2(0, 0);
Geom::Point point_b3(0, 0);
if (shift_nodes) {
- point3 = randomize();
- point_b3 = randomize();
+ point_a3 = randomize(max_lenght);
+ if(last){
+ point_b3 = randomize(max_lenght);
+ }
}
- if (shift_node_handles) {
- point1 = randomize();
- point2 = randomize();
- point_b1 = randomize();
- point_b2 = randomize();
+ if (shift_handles || shift_handles_sym) {
+ point_a1 = randomize(max_lenght);
+ point_a2 = randomize(max_lenght);
+ point_b1 = randomize(max_lenght);
+ if(last){
+ point_b2 = randomize(max_lenght);
+ }
} else {
- point2 = point3;
- point_b1 = point3;
- point_b2 = point_b3;
+ point_a2 = point_a3;
+ point_b1 = point_a3;
+ if(last){
+ point_b2 = point_b3;
+ }
}
- if (cubic) {
+ if(retract_handles){
+ out->moveto(A->initialPoint());
+ out->lineto(A->pointAt(t) + point_a3);
+ if(cubic && !last){
+ std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t);
+ std::vector<Geom::Point> seg2 = div.second.controlPoints();
+ out->curveto(seg2[1], seg2[2], seg2[3]);
+ } else {
+ out->lineto(A->finalPoint() + point_b3);
+ }
+ } else if(shift_handles_sym && cubic) {
+ std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t);
+ std::vector<Geom::Point> seg1 = div.first.controlPoints(),
+ seg2 = div.second.controlPoints();
+ Geom::Ray ray(prev,A->initialPoint());
+ point_a1 = Geom::Point::polar(ray.angle(), max_lenght);
+ if(prev == Geom::Point(0,0)){
+ point_a1 = randomize(max_lenght);
+ }
+ ray.setPoints(seg2[1] + point_a3 + point_b1, seg2[0] + point_a3);
+ point_a2 = Geom::Point::polar(ray.angle(), max_lenght);
+ if(last){
+ prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3;
+ } else {
+ prev = seg1[3] + point_a2 + point_a3;
+ }
+ out->moveto(seg1[0]);
+ out->curveto(seg1[0] + point_a1, seg1[3] + point_a2 + point_a3, seg1[3] + point_a3);
+ if(last){
+ out->curveto(seg2[1] + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, seg2[3] + point_b3);
+ } else {
+ out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3);
+ }
+ } else if(shift_handles_sym && !cubic) {
+ Geom::Ray ray(prev,A->initialPoint());
+ point_a1 = Geom::Point::polar(ray.angle(), max_lenght);
+ if(prev==Geom::Point(0,0)){
+ point_a1 = randomize(max_lenght);
+ }
+ ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3);
+ point_a2 = Geom::Point::polar(ray.angle(), max_lenght);
+ if(last){
+ prev = A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3;
+ } else {
+ prev = A->pointAt(t) + point_a3 + point_a2;
+ }
+ out->moveto(A->initialPoint());
+ out->curveto(A->initialPoint() + point_a1, A->pointAt(t) + point_a3 + point_a2, A->pointAt(t) + point_a3);
+ out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3);
+ } else if (cubic) {
std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t);
std::vector<Geom::Point> seg1 = div.first.controlPoints(),
seg2 = div.second.controlPoints();
out->moveto(seg1[0]);
- out->curveto(seg1[1] + point1, seg1[2] + point2, seg1[3] + point3);
- out->curveto(seg2[1] + point_b1, seg2[2], seg2[3]);
- } else if (shift_node_handles) {
+ out->curveto(seg1[1] + point_a1, seg1[2] + point_a2 + point_a3, seg1[3] + point_a3);
+ out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3);
+ } else if (shift_handles) {
out->moveto(A->initialPoint());
- out->curveto(A->pointAt(t / 3) + point1, A->pointAt((t / 3) * 2) + point2,
- A->pointAt(t) + point3);
- out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t + ((t / 3) * 2)),
- A->finalPoint());
+ out->curveto(A->pointAt(t / 3) + point_a1, A->pointAt((t / 3) * 2) + point_a2 + point_a3, A->pointAt(t) + point_a3);
+ out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3);
} else {
out->moveto(A->initialPoint());
- out->lineto(A->pointAt(t) + point3);
- out->lineto(A->finalPoint());
+ out->lineto(A->pointAt(t) + point_a3);
+ out->lineto(A->finalPoint() + point_b3);
}
return out;
}
-SPCurve *LPERoughen::jitter(const Geom::Curve *A)
+SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev)
{
SPCurve *out = new SPCurve();
Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*A);
- Geom::Point point1(0, 0);
- Geom::Point point2(0, 0);
- Geom::Point point3(0, 0);
+ double max_lenght = Geom::distance(A->initialPoint(),A->finalPoint()) / 3.0;
+ Geom::Point point_a1(0, 0);
+ Geom::Point point_a2(0, 0);
+ Geom::Point point_a3(0, 0);
if (shift_nodes) {
- point3 = randomize();
+ point_a3 = randomize(max_lenght);
}
- if (shift_node_handles) {
- point1 = randomize();
- point2 = randomize();
- } else {
- point2 = point3;
+ if (shift_handles || shift_handles_sym) {
+ point_a1 = randomize(max_lenght);
+ point_a2 = randomize(max_lenght);
}
- if (cubic) {
+ if(retract_handles){
+ out->moveto(A->initialPoint());
+ out->lineto(A->finalPoint() + point_a3);
+ } else if(shift_handles_sym && cubic) {
+ Geom::Ray ray(prev,A->initialPoint());
+ point_a1 = Geom::Point::polar(ray.angle(), max_lenght);
+ if(prev == Geom::Point(0,0)){
+ point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght);
+ }
+ prev = (*cubic)[2] + point_a2;
+ out->moveto((*cubic)[0]);
+ out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3);
+ } else if(shift_handles_sym && !cubic) {
+ Geom::Ray ray(prev,A->initialPoint());
+ point_a1 = Geom::Point::polar(ray.angle(), max_lenght);
+ if(prev==Geom::Point(0,0)){
+ point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght);
+ }
+ prev = A->pointAt((1.0/3.0) * 2) + point_a2;
+ out->moveto(A->initialPoint());
+ out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3, A->finalPoint() + point_a3);
+ } else if (cubic) {
out->moveto((*cubic)[0]);
- out->curveto((*cubic)[1] + point1, (*cubic)[2] + point2, (*cubic)[3] + point3);
- } else if (shift_node_handles) {
+ out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3);
+ } else if (shift_handles) {
out->moveto(A->initialPoint());
- out->curveto(A->pointAt(0.3333) + point1, A->pointAt(0.6666) + point2,
- A->finalPoint() + point3);
+ out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2 + point_a3,
+ A->finalPoint() + point_a3);
} else {
out->moveto(A->initialPoint());
- out->lineto(A->finalPoint() + point3);
+ out->lineto(A->finalPoint() + point_a3);
}
return out;
}
diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h
index 2b285cd40..57a516310 100644
--- a/src/live_effects/lpe-roughen.h
+++ b/src/live_effects/lpe-roughen.h
@@ -36,10 +36,10 @@ public:
virtual void doEffect(SPCurve *curve);
virtual double sign(double randNumber);
- virtual Geom::Point randomize();
+ virtual Geom::Point randomize(double max_lenght);
virtual void doBeforeEffect(SPLPEItem const * lpeitem);
- virtual SPCurve *addNodesAndJitter(const Geom::Curve *A, double t);
- virtual SPCurve *jitter(const Geom::Curve *A);
+ virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last);
+ virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev);
virtual Geom::Point tPoint(Geom::Point A, Geom::Point B, double t = 0.5);
virtual Gtk::Widget *newWidget();
@@ -51,7 +51,10 @@ private:
RandomParam displace_y;
RandomParam global_randomize;
BoolParam shift_nodes;
- BoolParam shift_node_handles;
+ BoolParam shift_handles;
+ BoolParam retract_handles;
+ BoolParam shift_handles_sym;
+ BoolParam fixed_displacement;
LPERoughen(const LPERoughen &);
LPERoughen &operator=(const LPERoughen &);
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index 634d56aa6..7302f9de6 100644
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
@@ -637,7 +637,6 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(IntermSnapResults &isr,
constraint_line.appendNew<Geom::LineSegment>(p_max_on_cl);
constraint_path.push_back(constraint_line);
}
- // Length of constraint_path will always be one
bool strict_snapping = _snapmanager->snapprefs.getStrictSnapping();
@@ -646,45 +645,15 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(IntermSnapResults &isr,
for (std::vector<SnapCandidatePath >::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); ++k) {
if (k->path_vector && _allowSourceToSnapToTarget(p.getSourceType(), (*k).target_type, strict_snapping)) {
// Do the intersection math
- Geom::CrossingSet cs = Geom::crossings(constraint_path, *(k->path_vector));
- // Store the results as intersection points
- unsigned int index = 0;
- for (Geom::CrossingSet::const_iterator i = cs.begin(); i != cs.end(); ++i) {
- if (index >= constraint_path.size()) {
- break;
- }
- // Reconstruct and store the points of intersection
- for (Geom::Crossings::const_iterator m = (*i).begin(); m != (*i).end(); ++m) {
- intersections.push_back(constraint_path[index].pointAt((*m).ta));
- }
- index++;
- }
-
- //Geom::crossings will not consider the closing segment apparently, so we'll handle that separately here
- //TODO: This should have been fixed in rev. #9859, which makes this workaround obsolete
- for(Geom::PathVector::iterator it_pv = k->path_vector->begin(); it_pv != k->path_vector->end(); ++it_pv) {
- if (it_pv->closed()) {
- // Get the closing linesegment and convert it to a path
- Geom::Path cls;
- cls.close(false);
- cls.append(it_pv->back_closed());
- // Intersect that closing path with the constrained path
- Geom::Crossings cs = Geom::crossings(constraint_path.front(), cls);
- // Reconstruct and store the points of intersection
- index = 0; // assuming the constraint path vector has only one path
- for (Geom::Crossings::const_iterator m = cs.begin(); m != cs.end(); ++m) {
- intersections.push_back(constraint_path[index].pointAt((*m).ta));
- }
- }
- }
+ std::vector<Geom::PVIntersection> inters = constraint_path.intersect(*(k->path_vector));
- // Convert the collected points of intersection to snapped points
- for (std::vector<Geom::Point>::iterator p_inters = intersections.begin(); p_inters != intersections.end(); ++p_inters) {
+ // Convert the collected intersections to snapped points
+ for (std::vector<Geom::PVIntersection>::const_iterator i = inters.begin(); i != inters.end(); ++i) {
// Convert to desktop coordinates
- (*p_inters) = dt->doc2dt(*p_inters);
+ Geom::Point p_inters = dt->doc2dt(i->point());
// Construct a snapped point
- Geom::Coord dist = Geom::L2(p.getPoint() - *p_inters);
- SnappedPoint s = SnappedPoint(*p_inters, p.getSourceType(), p.getSourceNum(), k->target_type, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true, false, k->target_bbox);
+ Geom::Coord dist = Geom::L2(p.getPoint() - p_inters);
+ SnappedPoint s = SnappedPoint(p_inters, p.getSourceType(), p.getSourceNum(), k->target_type, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true, false, k->target_bbox);
// Store the snapped point
if (dist <= tolerance) { // If the intersection is within snapping range, then we might snap to it
isr.points.push_back(s);
diff --git a/src/pure-transform.cpp b/src/pure-transform.cpp
index aa89c8a8e..9c7054b9f 100644
--- a/src/pure-transform.cpp
+++ b/src/pure-transform.cpp
@@ -63,7 +63,7 @@ void PureTransform::snap(::SnapManager *sm, std::vector<Inkscape::SnapCandidateP
(*j).setSourceNum(0);
first_free_snap = false;
}
- Inkscape::SnappedPoint snapped_point = snap(sm, *j, (*i).getPoint(), bbox);
+ Inkscape::SnappedPoint snapped_point = snap(sm, *j, (*i).getPoint(), bbox); // Calls the snap() method of the derived classes
// std::cout << "dist = " << snapped_point.getSnapDistance() << std::endl;
snapped_point.setPointerDistance(Geom::L2(pointer - (*i).getPoint()));
diff --git a/src/style-enums.h b/src/style-enums.h
index dfc99282c..03255b3b1 100644
--- a/src/style-enums.h
+++ b/src/style-enums.h
@@ -163,12 +163,6 @@ enum SPCSSDirection {
SP_CSS_DIRECTION_RTL
};
-enum SPCSSBlockProgression {
- SP_CSS_BLOCK_PROGRESSION_TB,
- SP_CSS_BLOCK_PROGRESSION_RL,
- SP_CSS_BLOCK_PROGRESSION_LR
-};
-
enum SPCSSWritingMode {
SP_CSS_WRITING_MODE_LR_TB,
SP_CSS_WRITING_MODE_RL_TB,
@@ -176,6 +170,16 @@ enum SPCSSWritingMode {
SP_CSS_WRITING_MODE_TB_LR
};
+// CSS WRITING MODES 3
+enum SPCSSTextOrientation {
+ SP_CSS_TEXT_ORIENTATION_MIXED,
+ SP_CSS_TEXT_ORIENTATION_UPRIGHT,
+ SP_CSS_TEXT_ORIENTATION_SIDEWAYS_RIGHT,
+ SP_CSS_TEXT_ORIENTATION_SIDEWAYS_LEFT,
+ SP_CSS_TEXT_ORIENTATION_SIDEWAYS,
+ SP_CSS_TEXT_ORIENTATION_USE_GLYPH_ORIENTATION
+};
+
enum SPTextAnchor {
SP_CSS_TEXT_ANCHOR_START,
SP_CSS_TEXT_ANCHOR_MIDDLE,
@@ -489,13 +493,6 @@ static SPStyleEnum const enum_direction[] = {
{NULL, -1}
};
-static SPStyleEnum const enum_block_progression[] = {
- {"tb", SP_CSS_BLOCK_PROGRESSION_TB},
- {"rl", SP_CSS_BLOCK_PROGRESSION_RL},
- {"lr", SP_CSS_BLOCK_PROGRESSION_LR},
- {NULL, -1}
-};
-
static SPStyleEnum const enum_writing_mode[] = {
/* Note that using the same enumerator for lr as lr-tb means we write as lr-tb even if the
* input file said lr. We prefer writing lr-tb on the grounds that the spec says the initial
@@ -504,12 +501,28 @@ static SPStyleEnum const enum_writing_mode[] = {
* ECMA scripts may be surprised to find tb-rl in DOM if they set the attribute to rl, so
* sharing enumerators for different strings may be a bug (once we support ecma script).
*/
+ // SVG 1.1 Deprecated but still must be supported in SVG 2.
{"lr-tb", SP_CSS_WRITING_MODE_LR_TB},
{"rl-tb", SP_CSS_WRITING_MODE_RL_TB},
{"tb-rl", SP_CSS_WRITING_MODE_TB_RL},
{"lr", SP_CSS_WRITING_MODE_LR_TB},
{"rl", SP_CSS_WRITING_MODE_RL_TB},
{"tb", SP_CSS_WRITING_MODE_TB_RL},
+ // SVG 2 & CSS 3 Writing Modes
+ {"horizontal-tb", SP_CSS_WRITING_MODE_LR_TB}, // This is correct, 'direction' distinguishes between 'lr' and 'rl'.
+ {"vertical-rl", SP_CSS_WRITING_MODE_TB_RL},
+ {"vertical-lr", SP_CSS_WRITING_MODE_TB_LR},
+ {NULL, -1}
+};
+
+// CSS WRITING MODES 3
+static SPStyleEnum const enum_text_orientation[] = {
+ {"mixed", SP_CSS_TEXT_ORIENTATION_MIXED}, // Default
+ {"upright", SP_CSS_TEXT_ORIENTATION_UPRIGHT},
+ {"sideways-right", SP_CSS_TEXT_ORIENTATION_SIDEWAYS_RIGHT},
+ {"sideways-left", SP_CSS_TEXT_ORIENTATION_SIDEWAYS_LEFT},
+ {"sideways", SP_CSS_TEXT_ORIENTATION_SIDEWAYS},
+ {"use-glyph-orientation", SP_CSS_TEXT_ORIENTATION_USE_GLYPH_ORIENTATION},
{NULL, -1}
};
diff --git a/src/style.cpp b/src/style.cpp
index 0cb5db0a7..369127792 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -136,8 +136,8 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) :
text_transform( "text-transform", enum_text_transform, SP_CSS_TEXT_TRANSFORM_NONE ),
direction( "direction", enum_direction, SP_CSS_DIRECTION_LTR ),
- block_progression("block-progression", enum_block_progression, SP_CSS_BLOCK_PROGRESSION_TB),
writing_mode( "writing-mode", enum_writing_mode, SP_CSS_WRITING_MODE_LR_TB ),
+ text_orientation( "text-orientation",enum_text_orientation,SP_CSS_TEXT_ORIENTATION_MIXED ),
baseline_shift(),
text_anchor( "text-anchor", enum_text_anchor, SP_CSS_TEXT_ANCHOR_START ),
white_space( "white-space", enum_white_space, SP_CSS_WHITE_SPACE_NORMAL ),
@@ -318,9 +318,9 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) :
_properties.push_back( &word_spacing );
_properties.push_back( &text_transform );
- _properties.push_back( &direction );
- _properties.push_back( &block_progression );
_properties.push_back( &writing_mode );
+ _properties.push_back( &direction );
+ _properties.push_back( &text_orientation );
_properties.push_back( &baseline_shift );
_properties.push_back( &text_anchor );
_properties.push_back( &white_space );
@@ -413,8 +413,8 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) :
// _propmap.insert( std::make_pair( text_transform.name, reinterpret_cast<SPIBasePtr>(&SPStyle::text_transform ) ) );
// _propmap.insert( std::make_pair( direction.name, reinterpret_cast<SPIBasePtr>(&SPStyle::direction ) ) );
- // _propmap.insert( std::make_pair( block_progression.name, reinterpret_cast<SPIBasePtr>(&SPStyle::block_progression ) ) );
// _propmap.insert( std::make_pair( writing_mode.name, reinterpret_cast<SPIBasePtr>(&SPStyle::writing_mode ) ) );
+ // _propmap.insert( std::make_pair( text_orientation.name, reinterpret_cast<SPIBasePtr>(&SPStyle::text_orientation ) ) );
// _propmap.insert( std::make_pair( baseline_shift.name, reinterpret_cast<SPIBasePtr>(&SPStyle::baseline_shift ) ) );
// _propmap.insert( std::make_pair( text_anchor.name, reinterpret_cast<SPIBasePtr>(&SPStyle::text_anchor ) ) );
// _propmap.insert( std::make_pair( white_space.name, reinterpret_cast<SPIBasePtr>(&SPStyle::white_space ) ) );
@@ -778,12 +778,12 @@ SPStyle::readIfUnset( gint id, gchar const *val ) {
case SP_PROP_DIRECTION:
direction.readIfUnset( val );
break;
- case SP_PROP_BLOCK_PROGRESSION:
- block_progression.readIfUnset( val );
- break;
case SP_PROP_WRITING_MODE:
writing_mode.readIfUnset( val );
break;
+ case SP_PROP_TEXT_ORIENTATION:
+ text_orientation.readIfUnset( val );
+ break;
case SP_PROP_TEXT_ANCHOR:
text_anchor.readIfUnset( val );
break;
@@ -1689,16 +1689,19 @@ sp_style_unset_property_attrs(SPObject *o)
repr->setAttribute("text-anchor", NULL);
}
if (style->white_space.set) {
- repr->setAttribute("white_space", NULL);
+ repr->setAttribute("white-space", NULL);
}
if (style->shape_inside.set) {
- repr->setAttribute("shape_inside", NULL);
+ repr->setAttribute("shape-inside", NULL);
}
if (style->shape_padding.set) {
- repr->setAttribute("shape_padding", NULL);
+ repr->setAttribute("shape-padding", NULL);
}
if (style->writing_mode.set) {
- repr->setAttribute("writing_mode", NULL);
+ repr->setAttribute("writing-mode", NULL);
+ }
+ if (style->text_orientation.set) {
+ repr->setAttribute("text-orientation", NULL);
}
if (style->filter.set) {
repr->setAttribute("filter", NULL);
@@ -1781,8 +1784,8 @@ sp_css_attr_unset_text(SPCSSAttr *css)
sp_repr_css_set_property(css, "word-spacing", NULL);
sp_repr_css_set_property(css, "text-transform", NULL);
sp_repr_css_set_property(css, "direction", NULL);
- sp_repr_css_set_property(css, "block-progression", NULL);
sp_repr_css_set_property(css, "writing-mode", NULL);
+ sp_repr_css_set_property(css, "text-orientation", NULL);
sp_repr_css_set_property(css, "text-anchor", NULL);
sp_repr_css_set_property(css, "white-space", NULL);
sp_repr_css_set_property(css, "shape-inside", NULL);
diff --git a/src/style.h b/src/style.h
index 02432d3e7..3948b876c 100644
--- a/src/style.h
+++ b/src/style.h
@@ -142,12 +142,12 @@ public:
SPIEnum text_transform;
/* CSS3 Text */
- /** text direction (css3 text 3.2) */
+ /** text direction (svg1.1) */
SPIEnum direction;
- /** block progression (css3 text 3.2) */
- SPIEnum block_progression;
- /** Writing mode (css3 text 3.2 and svg1.1 10.7.2) */
+ /** Writing mode (svg1.1 10.7.2, CSS Writing Modes 3) */
SPIEnum writing_mode;
+ /** Text orientation (CSS Writing Modes 3) */
+ SPIEnum text_orientation;
/** Baseline shift (svg1.1 10.9.2) */
SPIBaselineShift baseline_shift;
diff --git a/src/uri-references.cpp b/src/uri-references.cpp
index 04f904d39..b6ccdbf5f 100644
--- a/src/uri-references.cpp
+++ b/src/uri-references.cpp
@@ -26,73 +26,91 @@
namespace Inkscape {
URIReference::URIReference(SPObject *owner)
- : _owner(owner), _owner_document(NULL), _obj(NULL), _uri(NULL)
+ : _owner(owner)
+ , _owner_document(NULL)
+ , _obj(NULL)
+ , _uri(NULL)
{
g_assert(_owner != NULL);
/* FIXME !!! attach to owner's destroy signal to clean up in case */
}
URIReference::URIReference(SPDocument *owner_document)
- : _owner(NULL), _owner_document(owner_document), _obj(NULL), _uri(NULL)
+ : _owner(NULL)
+ , _owner_document(owner_document)
+ , _obj(NULL)
+ , _uri(NULL)
{
g_assert(_owner_document != NULL);
}
-URIReference::~URIReference()
-{
- detach();
-}
+URIReference::~URIReference() { detach(); }
/*
* The main ideas here are:
* (1) "If we are inside a clone, then we can accept if and only if our "original thing" can accept the reference"
- * (this caused problems when there are clones because a change in ids triggers signals for the object hrefing this id, but also its cloned reprs
- * (descendants of <use> referencing an ancestor of the href'ing object)). The way it is done here is *atrocious*, but i could not find a better way.
+ * (this caused problems when there are clones because a change in ids triggers signals for the object hrefing this id,
+ *but also its cloned reprs
+ * (descendants of <use> referencing an ancestor of the href'ing object)). The way it is done here is *atrocious*, but i
+ *could not find a better way.
* FIXME: find a better and safer way to find the "original object" of anyone with the flag ->cloned
*
- * (2) Once we have an (potential owner) object, it can accept a href to obj, iff the graph of objects where directed edges are
+ * (2) Once we have an (potential owner) object, it can accept a href to obj, iff the graph of objects where directed
+ *edges are
* either parent->child relations , *** or href'ing to href'ed *** relations, stays acyclic.
- * We can go either from owner and up in the tree, or from obj and down, in either case this will be in the worst case linear in the number of objects.
- * There are no easy objects allowing to do the second proposition, while "hrefList" is a "list of objects href'ing us", so we'll take this.
+ * We can go either from owner and up in the tree, or from obj and down, in either case this will be in the worst case
+ *linear in the number of objects.
+ * There are no easy objects allowing to do the second proposition, while "hrefList" is a "list of objects href'ing us",
+ *so we'll take this.
* Then we keep a set of already visited elements, and do a DFS on this graph. if we find obj, then BOOM.
*/
-bool URIReference::_acceptObject(SPObject *obj) const {
- //we go back following hrefList and parent to find if the object already references ourselves indirectly
- std::set<SPObject*> done;
- SPObject * owner = getOwner();
- if(!owner)return true;
- while(owner->cloned){
- std::vector<int> positions;
- while(owner->cloned){
- int position=0;
- SPObject* c = owner->parent->firstChild();
- while(c != owner && dynamic_cast<SPObject*>(c) ){position++;c=c->next;}
- positions.push_back(position);
- owner=owner->parent;
- }
- owner = ((SPUse*)owner)->get_original();
- for(int i=positions.size()-2;i>=0;i--)owner=owner->childList(false)[positions[i]];
- }
- //once we have the "original" object (hopefully) we look at who is referencing it
- std::list<SPObject*> todo(owner->hrefList);
- todo.push_front(owner->parent);
- while(!todo.empty()){
- SPObject* e = todo.front();
- todo.pop_front();
- if(!dynamic_cast<SPObject*>(e))continue;
- if(done.insert(e).second){
- if(e==obj){return false;}
- todo.push_front(e->parent);
- todo.insert(todo.begin(),e->hrefList.begin(),e->hrefList.end());
- }
- }
+bool URIReference::_acceptObject(SPObject *obj) const
+{
+ // we go back following hrefList and parent to find if the object already references ourselves indirectly
+ std::set<SPObject *> done;
+ SPObject *owner = getOwner();
+ if (!owner)
+ return true;
+ while (owner->cloned) {
+ std::vector<int> positions;
+ while (owner->cloned) {
+ int position = 0;
+ SPObject *c = owner->parent->firstChild();
+ while (c != owner && dynamic_cast<SPObject *>(c)) {
+ position++;
+ c = c->next;
+ }
+ positions.push_back(position);
+ owner = owner->parent;
+ }
+ owner = ((SPUse *)owner)->get_original();
+ for (int i = positions.size() - 2; i >= 0; i--)
+ owner = owner->childList(false)[positions[i]];
+ }
+ // once we have the "original" object (hopefully) we look at who is referencing it
+ if (obj == owner)
+ return false;
+ std::list<SPObject *> todo(owner->hrefList);
+ todo.push_front(owner->parent);
+ while (!todo.empty()) {
+ SPObject *e = todo.front();
+ todo.pop_front();
+ if (!dynamic_cast<SPObject *>(e))
+ continue;
+ if (done.insert(e).second) {
+ if (e == obj) {
+ return false;
+ }
+ todo.push_front(e->parent);
+ todo.insert(todo.begin(), e->hrefList.begin(), e->hrefList.end());
+ }
+ }
return true;
}
-
void URIReference::attach(const URI &uri) throw(BadURIException)
{
SPDocument *document = NULL;
@@ -108,32 +126,30 @@ void URIReference::attach(const URI &uri) throw(BadURIException)
// PNG and JPG files are allowed (in the case of feImage).
gchar *filename = uri.toString();
bool skip = false;
- if( g_str_has_suffix( filename, ".jpg" ) ||
- g_str_has_suffix( filename, ".JPG" ) ||
- g_str_has_suffix( filename, ".png" ) ||
- g_str_has_suffix( filename, ".PNG" ) ) {
+ if (g_str_has_suffix(filename, ".jpg") || g_str_has_suffix(filename, ".JPG") ||
+ g_str_has_suffix(filename, ".png") || g_str_has_suffix(filename, ".PNG")) {
skip = true;
}
-
+
// The path contains references to separate document files to load.
- if(document && uri.getPath() && !skip ) {
+ if (document && uri.getPath() && !skip) {
std::string base = document->getBase() ? document->getBase() : "";
std::string path = uri.getFullPath(base);
- if(!path.empty()) {
+ if (!path.empty()) {
document = document->createChildDoc(path);
} else {
document = NULL;
}
}
- if(!document) {
+ if (!document) {
g_warning("Can't get document for referenced URI: %s", filename);
- g_free( filename );
+ g_free(filename);
return;
}
- g_free( filename );
+ g_free(filename);
gchar const *fragment = uri.getFragment();
- if ( !uri.isRelative() || uri.getQuery() || !fragment ) {
+ if (!uri.isRelative() || uri.getQuery() || !fragment) {
throw UnsupportedURIException();
}
@@ -148,9 +164,9 @@ void URIReference::attach(const URI &uri) throw(BadURIException)
the strlen calculation and validity testing to before strdup, and copying just
the id without the "))". -- pjrm */
if (!strncmp(fragment, "xpointer(id(", 12)) {
- id = g_strdup(fragment+12);
+ id = g_strdup(fragment + 12);
size_t const len = strlen(id);
- if ( len < 3 || strcmp(id+len-2, "))") ) {
+ if (len < 3 || strcmp(id + len - 2, "))")) {
g_free(id);
throw MalformedURIException();
}
@@ -183,13 +199,14 @@ void URIReference::detach()
void URIReference::_setObject(SPObject *obj)
{
- if ( obj && !_acceptObject(obj) ) {
+ if (obj && !_acceptObject(obj)) {
obj = NULL;
}
- if ( obj == _obj ) return;
+ if (obj == _obj)
+ return;
- SPObject *old_obj=_obj;
+ SPObject *old_obj = _obj;
_obj = obj;
_release_connection.disconnect();
@@ -210,7 +227,7 @@ void URIReference::_setObject(SPObject *obj)
*/
void URIReference::_release(SPObject *obj)
{
- g_assert( _obj == obj );
+ g_assert(_obj == obj);
_setObject(NULL);
}
@@ -218,28 +235,27 @@ void URIReference::_release(SPObject *obj)
-SPObject* sp_css_uri_reference_resolve( SPDocument *document, const gchar *uri )
+SPObject *sp_css_uri_reference_resolve(SPDocument *document, const gchar *uri)
{
- SPObject* ref = NULL;
+ SPObject *ref = NULL;
- if ( document && uri && ( strncmp(uri, "url(", 4) == 0 ) ) {
- gchar *trimmed = extract_uri( uri );
- if ( trimmed ) {
- ref = sp_uri_reference_resolve( document, trimmed );
- g_free( trimmed );
+ if (document && uri && (strncmp(uri, "url(", 4) == 0)) {
+ gchar *trimmed = extract_uri(uri);
+ if (trimmed) {
+ ref = sp_uri_reference_resolve(document, trimmed);
+ g_free(trimmed);
}
}
return ref;
}
-SPObject *
-sp_uri_reference_resolve (SPDocument *document, const gchar *uri)
+SPObject *sp_uri_reference_resolve(SPDocument *document, const gchar *uri)
{
- SPObject* ref = NULL;
+ SPObject *ref = NULL;
- if ( uri && (*uri == '#') ) {
- ref = document->getObjectById( uri + 1 );
+ if (uri && (*uri == '#')) {
+ ref = document->getObjectById(uri + 1);
}
return ref;
diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp
index 259d4c9af..8e92f589a 100644
--- a/src/widgets/gradient-vector.cpp
+++ b/src/widgets/gradient-vector.cpp
@@ -842,7 +842,8 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s
GtkWidget *vb, *w, *f;
- g_return_val_if_fail(!gradient || SP_IS_GRADIENT(gradient), NULL);
+ g_return_val_if_fail(gradient != NULL, NULL);
+ g_return_val_if_fail(SP_IS_GRADIENT(gradient), NULL);
#if GTK_CHECK_VERSION(3,0,0)
vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, PAD);