summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2016-03-24 01:28:21 +0000
committerJabiertxof <jtx@jtx.marker.es>2016-03-24 01:28:21 +0000
commit718f5323cdab58042763107010fafbdc697c3c4f (patch)
tree164e442357777ac1714464415943e6869b901a8a /src
parentFixing Krzysztof review (diff)
parent"Backport" some Krzysztof review parts of mirror symmetry LPE also hapens on ... (diff)
downloadinkscape-718f5323cdab58042763107010fafbdc697c3c4f.tar.gz
inkscape-718f5323cdab58042763107010fafbdc697c3c4f.zip
update to trunk
(bzr r13682.1.37)
Diffstat (limited to 'src')
-rw-r--r--src/desktop-style.cpp102
-rw-r--r--src/extension/dbus/document-interface.cpp2
-rw-r--r--src/extension/implementation/script.cpp38
-rw-r--r--src/extension/implementation/script.h45
-rw-r--r--src/libnrtype/Layout-TNG.cpp2
-rw-r--r--src/live_effects/lpe-copy_rotate.cpp31
-rw-r--r--src/sp-text.cpp9
-rw-r--r--src/style.cpp7
-rw-r--r--src/svg/svg-length-test.h5
-rw-r--r--src/svg/svg-length.cpp20
-rw-r--r--src/svg/svg-length.h2
-rw-r--r--src/ui/draw-anchor.cpp9
-rw-r--r--src/ui/interface.cpp2
-rw-r--r--src/ui/tools/pen-tool.cpp21
-rw-r--r--src/ui/widget/preferences-widget.cpp4
-rw-r--r--src/ui/widget/unit-tracker.h2
-rw-r--r--src/util/units.cpp35
-rw-r--r--src/util/units.h3
-rw-r--r--src/widgets/select-toolbar.cpp113
-rw-r--r--src/widgets/text-toolbar.cpp307
-rw-r--r--src/widgets/toolbox.cpp4
21 files changed, 470 insertions, 293 deletions
diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp
index d10c75cd8..5f6441aa7 100644
--- a/src/desktop-style.cpp
+++ b/src/desktop-style.cpp
@@ -1036,20 +1036,24 @@ int
objects_query_fontnumbers (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
bool different = false;
+ bool different_lineheight = false;
+ bool different_lineheight_unit = false;
double size = 0;
double letterspacing = 0;
double wordspacing = 0;
- double linespacing = 0;
+ double lineheight = 0;
bool letterspacing_normal = false;
bool wordspacing_normal = false;
- bool linespacing_normal = false;
+ bool lineheight_normal = false;
+ bool lineheight_unit_proportional = false;
+ bool lineheight_unit_absolute = false;
double size_prev = 0;
double letterspacing_prev = 0;
double wordspacing_prev = 0;
- double linespacing_prev = 0;
- int linespacing_unit = 0;
+ double lineheight_prev = 0;
+ int lineheight_unit_prev = -1;
int texts = 0;
int no_size = 0;
@@ -1094,36 +1098,55 @@ objects_query_fontnumbers (const std::vector<SPItem*> &objects, SPStyle *style_r
wordspacing_normal = false;
}
- double linespacing_current;
+ // If all line spacing units the same, use that (average line spacing).
+ // Else if all line spacings absolute, use 'px' (average line spacing).
+ // Else if all line spacings proportional, use % (average line spacing).
+ // Else use default.
+ double lineheight_current;
+ int lineheight_unit_current;
if (style->line_height.normal) {
- linespacing_current = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL;
- if (!different && (linespacing_prev == 0 || linespacing_prev == linespacing_current))
- linespacing_normal = true;
- } else if (style->line_height.unit == SP_CSS_UNIT_PERCENT || style->font_size.computed == 0) {
- linespacing_current = style->line_height.value;
- linespacing_normal = false;
+ lineheight_current = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL;
+ lineheight_unit_current = SP_CSS_UNIT_NONE;
+ if (!different_lineheight &&
+ (lineheight_prev == 0 || lineheight_prev == lineheight_current))
+ lineheight_normal = true;
+ } else if (style->line_height.unit == SP_CSS_UNIT_NONE ||
+ style->line_height.unit == SP_CSS_UNIT_PERCENT ||
+ style->line_height.unit == SP_CSS_UNIT_EM ||
+ style->line_height.unit == SP_CSS_UNIT_EX ||
+ style->font_size.computed == 0) {
+ lineheight_current = style->line_height.value;
+ lineheight_unit_current = style->line_height.unit;
+ lineheight_unit_proportional = true;
+ lineheight_normal = false;
} else {
- linespacing_current = style->line_height.computed;
- linespacing_normal = false;
+ // Always 'px' internally
+ lineheight_current = style->line_height.computed;
+ lineheight_unit_current = style->line_height.unit;
+ lineheight_unit_absolute = true;
+ lineheight_normal = false;
}
- if (linespacing_unit == 0) {
- linespacing_unit = style->line_height.unit;
- } else if (linespacing_unit != style->line_height.unit) {
- linespacing_unit = SP_CSS_UNIT_PERCENT;
- }
- linespacing += linespacing_current;
+ lineheight += lineheight_current;
if ((size_prev != 0 && style->font_size.computed != size_prev) ||
(letterspacing_prev != 0 && style->letter_spacing.computed != letterspacing_prev) ||
- (wordspacing_prev != 0 && style->word_spacing.computed != wordspacing_prev) ||
- (linespacing_prev != 0 && linespacing_current != linespacing_prev)) {
+ (wordspacing_prev != 0 && style->word_spacing.computed != wordspacing_prev)) {
different = true;
}
+ if (lineheight_prev != 0 && lineheight_current != lineheight_prev) {
+ different_lineheight = true;
+ }
+
+ if (lineheight_unit_prev != -1 && lineheight_unit_current != lineheight_unit_prev) {
+ different_lineheight_unit = true;
+ }
+
size_prev = style->font_size.computed;
letterspacing_prev = style->letter_spacing.computed;
wordspacing_prev = style->word_spacing.computed;
- linespacing_prev = linespacing_current;
+ lineheight_prev = lineheight_current;
+ lineheight_unit_prev = lineheight_unit_current;
// FIXME: we must detect MULTIPLE_DIFFERENT for these too
style_res->text_anchor.computed = style->text_anchor.computed;
@@ -1139,7 +1162,7 @@ objects_query_fontnumbers (const std::vector<SPItem*> &objects, SPStyle *style_r
}
letterspacing /= texts;
wordspacing /= texts;
- linespacing /= texts;
+ lineheight /= texts;
}
style_res->font_size.computed = size;
@@ -1151,13 +1174,36 @@ objects_query_fontnumbers (const std::vector<SPItem*> &objects, SPStyle *style_r
style_res->word_spacing.normal = wordspacing_normal;
style_res->word_spacing.computed = wordspacing;
- style_res->line_height.normal = linespacing_normal;
- style_res->line_height.computed = linespacing;
- style_res->line_height.value = linespacing;
- style_res->line_height.unit = linespacing_unit;
+ style_res->line_height.normal = lineheight_normal;
+ style_res->line_height.computed = lineheight;
+ style_res->line_height.value = lineheight;
+ if (different_lineheight_unit) {
+ if (lineheight_unit_absolute && !lineheight_unit_proportional) {
+ // Mixture of absolute units
+ style_res->line_height.unit = SP_CSS_UNIT_PX;
+ } else {
+ // Mixture of relative units
+ style_res->line_height.unit = SP_CSS_UNIT_PERCENT;
+ }
+ if (lineheight_unit_absolute && lineheight_unit_proportional) {
+ // Mixed types of units, fallback to default
+ style_res->line_height.computed = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL * 100.0;
+ style_res->line_height.value = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL * 100.0;
+ }
+ } else {
+ // Same units.
+ if (lineheight_unit_prev != -1) {
+ style_res->line_height.unit = lineheight_unit_prev;
+ } else {
+ // No text object... use default.
+ style_res->line_height.unit = SP_CSS_UNIT_NONE;
+ style_res->line_height.computed = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL;
+ style_res->line_height.value = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL;
+ }
+ }
if (texts > 1) {
- if (different) {
+ if (different || different_lineheight) {
return QUERY_STYLE_MULTIPLE_AVERAGED;
} else {
return QUERY_STYLE_MULTIPLE_SAME;
diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp
index d64bdbc5c..121a49a25 100644
--- a/src/extension/dbus/document-interface.cpp
+++ b/src/extension/dbus/document-interface.cpp
@@ -1,7 +1,7 @@
/*
* This is where the implementation of the DBus based document API lives.
* All the methods in here (except in the helper section) are
- * designed to be called remotly via DBus. application-interface.cpp
+ * designed to be called remotely via DBus. application-interface.cpp
* has the methods used to connect to the bus and get a document instance.
*
* Documentation for these methods is in document-interface.xml
diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp
index 2ec17f947..9aaf4b952 100644
--- a/src/extension/implementation/script.cpp
+++ b/src/extension/implementation/script.cpp
@@ -1119,7 +1119,45 @@ int Script::execute (const std::list<std::string> &in_command,
}
+void Script::file_listener::init(int fd, Glib::RefPtr<Glib::MainLoop> main) {
+ _channel = Glib::IOChannel::create_from_fd(fd);
+ _channel->set_encoding();
+ _conn = main->get_context()->signal_io().connect(sigc::mem_fun(*this, &file_listener::read), _channel, Glib::IO_IN | Glib::IO_HUP | Glib::IO_ERR);
+ _main_loop = main;
+ return;
+}
+
+bool Script::file_listener::read(Glib::IOCondition condition) {
+ if (condition != Glib::IO_IN) {
+ _main_loop->quit();
+ return false;
+ }
+
+ Glib::IOStatus status;
+ Glib::ustring out;
+ status = _channel->read_line(out);
+ _string += out;
+
+ if (status != Glib::IO_STATUS_NORMAL) {
+ _main_loop->quit();
+ _dead = true;
+ return false;
+ }
+
+ return true;
+}
+
+bool Script::file_listener::toFile(const Glib::ustring &name) {
+ try {
+ Glib::RefPtr<Glib::IOChannel> stdout_file = Glib::IOChannel::create_from_file(name, "w");
+ stdout_file->set_encoding();
+ stdout_file->write(_string);
+ } catch (Glib::FileError &e) {
+ return false;
+ }
+ return true;
+}
} // namespace Implementation
} // namespace Extension
diff --git a/src/extension/implementation/script.h b/src/extension/implementation/script.h
index 4cf33c989..684719895 100644
--- a/src/extension/implementation/script.h
+++ b/src/extension/implementation/script.h
@@ -85,49 +85,10 @@ private:
};
bool isDead () { return _dead; }
-
- // TODO move these definitions into script.cpp
- void init (int fd, Glib::RefPtr<Glib::MainLoop> main) {
- _channel = Glib::IOChannel::create_from_fd(fd);
- _channel->set_encoding();
- _conn = main->get_context()->signal_io().connect(sigc::mem_fun(*this, &file_listener::read), _channel, Glib::IO_IN | Glib::IO_HUP | Glib::IO_ERR);
- _main_loop = main;
-
- return;
- };
-
- bool read (Glib::IOCondition condition) {
- if (condition != Glib::IO_IN) {
- _main_loop->quit();
- return false;
- }
-
- Glib::IOStatus status;
- Glib::ustring out;
- status = _channel->read_line(out);
- _string += out;
-
- if (status != Glib::IO_STATUS_NORMAL) {
- _main_loop->quit();
- _dead = true;
- return false;
- }
-
- return true;
- };
-
+ void init(int fd, Glib::RefPtr<Glib::MainLoop> main);
+ bool read(Glib::IOCondition condition);
Glib::ustring string (void) { return _string; };
-
- bool toFile (const Glib::ustring &name) {
- try {
- Glib::RefPtr<Glib::IOChannel> stdout_file = Glib::IOChannel::create_from_file(name, "w");
- stdout_file->set_encoding();
- stdout_file->write(_string);
- } catch (Glib::FileError &e) {
- return false;
- }
- return true;
- };
+ bool toFile(const Glib::ustring &name);
};
int execute (const std::list<std::string> &in_command,
diff --git a/src/libnrtype/Layout-TNG.cpp b/src/libnrtype/Layout-TNG.cpp
index ec488b584..8b0889188 100644
--- a/src/libnrtype/Layout-TNG.cpp
+++ b/src/libnrtype/Layout-TNG.cpp
@@ -14,7 +14,7 @@ namespace Inkscape {
namespace Text {
const gunichar Layout::UNICODE_SOFT_HYPHEN = 0x00AD;
-const double Layout::LINE_HEIGHT_NORMAL = 125;
+const double Layout::LINE_HEIGHT_NORMAL = 1.25;
Layout::Layout() :
_input_truncated(0),
diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp
index f204f8608..efea76039 100644
--- a/src/live_effects/lpe-copy_rotate.cpp
+++ b/src/live_effects/lpe-copy_rotate.cpp
@@ -44,14 +44,6 @@ public:
} // namespace CR
-int
-pointSideOfLine(Geom::Point const &A, Geom::Point const &B, Geom::Point const &X)
-{
- //http://stackoverflow.com/questions/1560492/how-to-tell-whether-a-point-is-to-the-right-or-left-side-of-a-line
- double pos = (B[Geom::X]-A[Geom::X])*(X[Geom::Y]-A[Geom::Y]) - (B[Geom::Y]-A[Geom::Y])*(X[Geom::X]-A[Geom::X]);
- return (pos < 0) ? -1 : (pos > 0);
-}
-
bool
pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const &p2, Geom::Point const &p3)
{
@@ -71,10 +63,10 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"),
starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0),
- rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0),
- num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5),
+ rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 60.0),
+ num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 6),
copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true),
- fuse_paths(_("Fuse paths"), _("Fuse paths by helper line"), "fuse_paths", &wr, this, false),
+ fuse_paths(_("Fuse paths"), _("Fuse paths by helper line, use fill-rule: evenodd for best result"), "fuse_paths", &wr, this, false),
dist_angle_handle(100.0)
{
show_orig_path = true;
@@ -143,6 +135,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem)
num_copies.param_set_increments(2,2);
if ((int)num_copies%2 !=0) {
num_copies.param_set_value(num_copies+1);
+ rotation_angle.param_set_value(360.0/(double)num_copies);
}
} else {
num_copies.param_set_increments(1,1);
@@ -181,10 +174,13 @@ LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const &divider)
std::sort(crossed.begin(), crossed.end());
for (unsigned int i = 0; i < crossed.size(); i++) {
double time_end = crossed[i];
+ if (time_start == time_end || time_end - time_start < Geom::EPSILON) {
+ continue;
+ }
Geom::Path portion_original = original.portion(time_start,time_end);
if (!portion_original.empty()) {
- Geom::Point side_checker = portion_original.pointAt(0.001);
- position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker);
+ Geom::Point side_checker = portion_original.pointAt(0.0001);
+ position = Geom::sgn(Geom::cross(divider[1].finalPoint() - divider[0].finalPoint(), side_checker - divider[0].finalPoint()));
if (rotation_angle != 180) {
position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint());
}
@@ -195,7 +191,7 @@ LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const &divider)
time_start = time_end;
}
}
- position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint());
+ position = Geom::sgn(Geom::cross(divider[1].finalPoint() - divider[0].finalPoint(), original.finalPoint() - divider[0].finalPoint()));
if (rotation_angle != 180) {
position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint());
}
@@ -242,13 +238,13 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s
if (i%2 != 0) {
Geom::Point A = (Geom::Point)origin;
Geom::Point B = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle*i)+starting_angle)) * size_divider;
- Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]);
+ Geom::Translate m1(A[0], A[1]);
double hyp = Geom::distance(A, B);
double c = (B[0] - A[0]) / hyp; // cos(alpha)
double s = (B[1] - A[1]) / hyp; // sin(alpha)
Geom::Affine m2(c, -s, s, c, 0.0, 0.0);
- Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
+ Geom::Scale sca(1.0, -1.0);
Geom::Affine tmp_m = m1.inverse() * m2;
m = tmp_m;
@@ -269,7 +265,6 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s
tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed();
tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint());
tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append);
- tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed();
} else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(), append_path.initialPoint())) {
Geom::Path tmp_append = append_path;
tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint());
@@ -279,7 +274,6 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s
tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed();
tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint());
tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append);
- tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed();
} else if (Geom::are_near(tmp_path_helper[0].finalPoint(), append_path.finalPoint())) {
Geom::Path tmp_append = append_path.reversed();
tmp_append.setInitial(tmp_path_helper[0].finalPoint());
@@ -289,7 +283,6 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s
tmp_path_helper[0] = tmp_path_helper[0].reversed();
tmp_append.setInitial(tmp_path_helper[0].finalPoint());
tmp_path_helper[0].append(tmp_append);
- tmp_path_helper[0] = tmp_path_helper[0].reversed();
} else {
tmp_path_helper.push_back(append_path);
}
diff --git a/src/sp-text.cpp b/src/sp-text.cpp
index 7d4348d19..da92ad8d4 100644
--- a/src/sp-text.cpp
+++ b/src/sp-text.cpp
@@ -302,6 +302,15 @@ Inkscape::XML::Node *SPText::write(Inkscape::XML::Document *xml_doc, Inkscape::X
this->attributes.writeTo(repr);
this->rebuildLayout(); // copied from update(), see LP Bug 1339305
+ // deprecated attribute, but keep it around for backwards compatibility
+ if (this->style->line_height.set && !this->style->line_height.inherit && !this->style->line_height.normal && this->style->line_height.unit == SP_CSS_UNIT_PERCENT) {
+ Inkscape::SVGOStringStream os;
+ os << (this->style->line_height.value * 100.0) << "%";
+ this->getRepr()->setAttribute("sodipodi:linespacing", os.str().c_str());
+ } else {
+ this->getRepr()->setAttribute("sodipodi:linespacing", NULL);
+ }
+
// SVG 2 Auto-wrapped text
if( this->width.computed > 0.0 ) {
sp_repr_set_svg_double(repr, "width", this->width.computed);
diff --git a/src/style.cpp b/src/style.cpp
index 99beaed22..1f98a50a3 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -113,7 +113,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) :
font_weight( "font-weight", enum_font_weight, SP_CSS_FONT_WEIGHT_NORMAL, SP_CSS_FONT_WEIGHT_400 ),
font_stretch( "font-stretch", enum_font_stretch, SP_CSS_FONT_STRETCH_NORMAL ),
font_size(),
- line_height( "line-height", 125 ), // SPILengthOrNormal
+ line_height( "line-height", 1.25 ), // SPILengthOrNormal
font_family( "font-family", "sans-serif" ), // SPIString w/default
font(), // SPIFont
font_specification( "-inkscape-font-specification" ), // SPIString
@@ -1510,7 +1510,8 @@ gchar const *
sp_style_get_css_unit_string(int unit)
{
// specify px by default, see inkscape bug 1221626, mozilla bug 234789
-
+ // This is a problematic fix as some properties (e.g. 'line-height') have
+ // different behaviour if there is no unit.
switch (unit) {
case SP_CSS_UNIT_NONE: return "px";
@@ -1957,7 +1958,7 @@ sp_css_attr_scale(SPCSSAttr *css, double ex)
sp_css_attr_scale_property_single(css, "kerning", ex);
sp_css_attr_scale_property_single(css, "letter-spacing", ex);
sp_css_attr_scale_property_single(css, "word-spacing", ex);
- //sp_css_attr_scale_property_single(css, "line-height", ex, true);
+ sp_css_attr_scale_property_single(css, "line-height", ex, true);
return css;
}
diff --git a/src/svg/svg-length-test.h b/src/svg/svg-length-test.h
index 0dac4854a..e73211ade 100644
--- a/src/svg/svg-length-test.h
+++ b/src/svg/svg-length-test.h
@@ -102,10 +102,7 @@ public:
for ( int i = (static_cast<int>(SVGLength::NONE) + 1); i <= static_cast<int>(SVGLength::LAST_UNIT); i++ ) {
SVGLength::Unit target = static_cast<SVGLength::Unit>(i);
// PX is a special case where we don't have a unit string
- // FOOT and MITRE are not CSS/SVG Units
- if ( (target != SVGLength::PX) &&
- (target != SVGLength::FOOT) &&
- (target != SVGLength::MITRE) ) {
+ if ( (target != SVGLength::PX) ) {
gchar const* val = sp_svg_length_get_css_units(target);
TSM_ASSERT_DIFFERS(i, val, "");
}
diff --git a/src/svg/svg-length.cpp b/src/svg/svg-length.cpp
index cd995582d..d22da69cd 100644
--- a/src/svg/svg-length.cpp
+++ b/src/svg/svg-length.cpp
@@ -411,14 +411,6 @@ So after the number, the string does not necessarily have a \0 or a unit, it mig
*computed = Inkscape::Util::Quantity::convert(v, "in", "px");
}
break;
- case UVAL('f','t'):
- if (unit) {
- *unit = SVGLength::FOOT;
- }
- if (computed) {
- *computed = Inkscape::Util::Quantity::convert(v, "ft", "px");
- }
- break;
case UVAL('e','m'):
if (unit) {
*unit = SVGLength::EM;
@@ -495,12 +487,6 @@ void SVGLength::set(SVGLength::Unit u, float v)
case INCH:
hack = "pt";
break;
- case FOOT:
- hack = "pt";
- break;
- case MITRE:
- hack = "m";
- break;
default:
break;
}
@@ -572,8 +558,6 @@ gchar const *sp_svg_length_get_css_units(SVGLength::Unit unit)
case SVGLength::MM: return "mm";
case SVGLength::CM: return "cm";
case SVGLength::INCH: return "in";
- case SVGLength::FOOT: return ""; // Not in SVG/CSS specification.
- case SVGLength::MITRE: return ""; // Not in SVG/CSS specification.
case SVGLength::EM: return "em";
case SVGLength::EX: return "ex";
case SVGLength::PERCENT: return "%";
@@ -590,10 +574,6 @@ std::string sp_svg_length_write_with_units(SVGLength const &length)
Inkscape::SVGOStringStream os;
if (length.unit == SVGLength::PERCENT) {
os << 100*length.value << sp_svg_length_get_css_units(length.unit);
- } else if (length.unit == SVGLength::FOOT) {
- os << 12*length.value << sp_svg_length_get_css_units(SVGLength::INCH);
- } else if (length.unit == SVGLength::MITRE) {
- os << 100*length.value << sp_svg_length_get_css_units(SVGLength::CM);
} else {
os << length.value << sp_svg_length_get_css_units(length.unit);
}
diff --git a/src/svg/svg-length.h b/src/svg/svg-length.h
index 2aaf248b1..bd3435ca6 100644
--- a/src/svg/svg-length.h
+++ b/src/svg/svg-length.h
@@ -27,8 +27,6 @@ public:
MM,
CM,
INCH,
- FOOT,
- MITRE,
EM,
EX,
PERCENT,
diff --git a/src/ui/draw-anchor.cpp b/src/ui/draw-anchor.cpp
index 6b9a88ed7..e5a7a493e 100644
--- a/src/ui/draw-anchor.cpp
+++ b/src/ui/draw-anchor.cpp
@@ -26,6 +26,9 @@ using Inkscape::ControlManager;
#define FILL_COLOR_NORMAL 0xffffff7f
#define FILL_COLOR_MOUSEOVER 0xff0000ff
+#define NODE_SIZE_NORMAL 7.0
+#define NODE_SIZE_MOUSEOVER 10.0
+
/**
* Creates an anchor object and initializes it.
*/
@@ -78,14 +81,16 @@ SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool acti
if ( activate && ( Geom::LInfty( w - anchor->dc->getDesktop().d2w(anchor->dp) ) <= (ctrl->box.width() / 2.0) ) ) {
if (!anchor->active) {
- g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_MOUSEOVER, NULL);
+ g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_MOUSEOVER,
+ "size", NODE_SIZE_MOUSEOVER, NULL);
anchor->active = TRUE;
}
return anchor;
}
if (anchor->active) {
- g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_NORMAL, NULL);
+ g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_NORMAL,
+ "size", NODE_SIZE_NORMAL, NULL);
anchor->active = FALSE;
}
return NULL;
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index 69b229519..531aa728d 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -1786,7 +1786,7 @@ void ContextMenu::MakeItemMenu (void)
/* Group */
mi = Gtk::manage(new Gtk::MenuItem(_("_Group"), 1));
mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateGroup));
- if (_desktop->selection->isEmpty() || _desktop->selection->single()) {
+ if (_desktop->selection->isEmpty()) {
mi->set_sensitive(FALSE);
} else {
mi->set_sensitive(TRUE);
diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp
index 2ed366a7d..18af8e105 100644
--- a/src/ui/tools/pen-tool.cpp
+++ b/src/ui/tools/pen-tool.cpp
@@ -1220,7 +1220,18 @@ bool PenTool::_handleKeyPress(GdkEvent *event) {
case GDK_KEY_KP_Enter:
if (this->npoints != 0) {
this->ea = NULL; // unset end anchor if set (otherwise crashes)
- this->_finish(false);
+ if(MOD__SHIFT_ONLY(event)) {
+ // All this is needed to stop the last control
+ // point dispeating and stop making an n-1 shape.
+ Geom::Point const p(0, 0);
+ if(this->red_curve->is_empty()) {
+ this->red_curve->moveto(p);
+ }
+ this->_finishSegment(p, 0);
+ this->_finish(true);
+ } else {
+ this->_finish(false);
+ }
ret = true;
}
break;
@@ -1783,12 +1794,12 @@ void PenTool::_setSubsequentPoint(Geom::Point const p, bool statusbar, guint sta
if (statusbar) {
gchar *message = is_curve ?
- _("<b>Curve segment</b>: angle %3.2f&#176;, distance %s; with <b>Ctrl</b> to snap angle, <b>Enter</b> to finish the path" ):
- _("<b>Line segment</b>: angle %3.2f&#176;, distance %s; with <b>Ctrl</b> to snap angle, <b>Enter</b> to finish the path");
+ _("<b>Curve segment</b>: angle %3.2f&#176;, distance %s; with <b>Ctrl</b> to snap angle, <b>Enter</b> or <b>Shift+Enter</b> to finish the path" ):
+ _("<b>Line segment</b>: angle %3.2f&#176;, distance %s; with <b>Ctrl</b> to snap angle, <b>Enter</b> or <b>Shift+Enter</b> to finish the path");
if(this->spiro || this->bspline){
message = is_curve ?
- _("<b>Curve segment</b>: angle %3.2f&#176;, distance %s; with <b>Shift+Click</b> make a cusp node, <b>Enter</b> to finish the path" ):
- _("<b>Line segment</b>: angle %3.2f&#176;, distance %s; with <b>Shift+Click</b> make a cusp node, <b>Enter</b> to finish the path");
+ _("<b>Curve segment</b>: angle %3.2f&#176;, distance %s; with <b>Shift+Click</b> make a cusp node, <b>Enter</b> or <b>Shift+Enter</b> to finish the path" ):
+ _("<b>Line segment</b>: angle %3.2f&#176;, distance %s; with <b>Shift+Click</b> make a cusp node, <b>Enter</b> or <b>Shift+Enter</b> to finish the path");
}
this->_setAngleDistanceStatusMessage(p, 0, message);
}
diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp
index e906762e3..d56506d62 100644
--- a/src/ui/widget/preferences-widget.cpp
+++ b/src/ui/widget/preferences-widget.cpp
@@ -468,12 +468,8 @@ ZoomCorrRuler::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) {
Glib::ustring abbr = prefs->getString("/options/zoomcorrection/unit");
if (abbr == "cm") {
draw_marks(cr, 0.1, 10);
- } else if (abbr == "ft") {
- draw_marks(cr, 1/12.0, 12);
} else if (abbr == "in") {
draw_marks(cr, 0.25, 4);
- } else if (abbr == "m") {
- draw_marks(cr, 1/10.0, 10);
} else if (abbr == "mm") {
draw_marks(cr, 10, 10);
} else if (abbr == "pc") {
diff --git a/src/ui/widget/unit-tracker.h b/src/ui/widget/unit-tracker.h
index 0fe5bda80..8fa9ff304 100644
--- a/src/ui/widget/unit-tracker.h
+++ b/src/ui/widget/unit-tracker.h
@@ -42,8 +42,8 @@ public:
Inkscape::Util::Unit const * getActiveUnit() const;
void addUnit(Inkscape::Util::Unit const *u);
- void prependUnit(Inkscape::Util::Unit const *u);
void addAdjustment(GtkAdjustment *adj);
+ void prependUnit(Inkscape::Util::Unit const *u);
void setFullVal(GtkAdjustment *adj, gdouble val);
GtkAction *createAction(gchar const *name, gchar const *label, gchar const *tooltip);
diff --git a/src/util/units.cpp b/src/util/units.cpp
index 2e7a3b1d2..cf4bfd146 100644
--- a/src/util/units.cpp
+++ b/src/util/units.cpp
@@ -81,21 +81,7 @@ unsigned const svg_length_lookup[] = {
UNIT_CODE_PERCENT
};
-/* From SP_CSS_UNIT_* to unit */
-unsigned const sp_css_unit_lookup[] = {
- 0,
- UNIT_CODE_PX,
- UNIT_CODE_PT,
- UNIT_CODE_PC,
- UNIT_CODE_MM,
- UNIT_CODE_CM,
- UNIT_CODE_IN,
- UNIT_CODE_EM,
- UNIT_CODE_EX,
- UNIT_CODE_PERCENT
- // UNIT_CODE_FT Missing,
- // UNIT_CODE_MT Missing,
-};
+
// maps unit codes obtained from their abbreviations to their SVGLength unit indexes
typedef INK_UNORDERED_MAP<unsigned, SVGLength::Unit> UnitCodeLookup;
@@ -227,10 +213,6 @@ bool Unit::compatibleWith(Glib::ustring const &u) const
{
return compatibleWith(unit_table.getUnit(u));
}
-bool Unit::compatibleWith(char const *u) const
-{
- return compatibleWith(unit_table.getUnit(u));
-}
bool Unit::operator==(Unit const &other) const
{
@@ -273,6 +255,8 @@ double Unit::convert(double from_dist, char const *to) const
return convert(from_dist, unit_table.getUnit(to));
}
+
+
Unit UnitTable::_empty_unit;
UnitTable::UnitTable()
@@ -323,19 +307,6 @@ Unit const *UnitTable::getUnit(SVGLength::Unit u) const
}
return &_empty_unit;
}
-/* SP_CSS_UNIT lookup */
-Unit const *UnitTable::getUnit(unsigned int u) const
-{
- if (u == 0 || u > 9) {
- return &_empty_unit;
- }
-
- UnitCodeMap::const_iterator f = _unit_map.find(sp_css_unit_lookup[u]);
- if (f != _unit_map.end()) {
- return &(*f->second);
- }
- return &_empty_unit;
-}
Unit const *UnitTable::findUnit(double factor, UnitType type) const
{
diff --git a/src/util/units.h b/src/util/units.h
index a840a37ec..fa70058ba 100644
--- a/src/util/units.h
+++ b/src/util/units.h
@@ -152,9 +152,6 @@ public:
/** Retrieve a given unit based on its SVGLength unit */
Unit const *getUnit(SVGLength::Unit u) const;
-
- /** Retrieve a given unit based on its SP_CSS_UNIT */
- Unit const *getUnit(unsigned int u) const;
/** Retrieve a quantity based on its string identifier */
Quantity parseQuantity(Glib::ustring const &q) const;
diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp
index 3cd6c0e28..9851b0606 100644
--- a/src/widgets/select-toolbar.cpp
+++ b/src/widgets/select-toolbar.cpp
@@ -437,58 +437,58 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb
// four spinbuttons
eact = create_adjustment_action(
- /* name= */ "XAction",
- /* label= */ C_("Select toolbar", "X position"),
- /* shortLabel= */ C_("Select toolbar", "X:"),
- /* tooltip= */ C_("Select toolbar", "Horizontal coordinate of selection"),
- /* path= */ "/tools/select/X",
- /* def(default) */ 0.0,
- /* focusTarget= */ GTK_WIDGET(desktop->canvas),
- /* dataKludge= */ G_OBJECT(spw),
- /* altx, altx_mark */ TRUE, "altx",
- /* lower, uppper, step, page */ -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
- /* descrLabels, descrValues, descrCount */ 0, 0, 0,
- /* callback= */ sp_object_layout_any_value_changed,
- /* unit_tracker= */ tracker,
- /* climb, digits, factor */ SPIN_STEP, 3, 1);
+ "XAction", /* name */
+ C_("Select toolbar", "X position"), /* label */
+ C_("Select toolbar", "X:"), /* shortLabel */
+ C_("Select toolbar", "Horizontal coordinate of selection"), /* tooltip */
+ "/tools/select/X", /* path */
+ 0.0, /* def(default) */
+ GTK_WIDGET(desktop->canvas), /* focusTarget */
+ G_OBJECT(spw), /* dataKludge */
+ TRUE, "altx", /* altx, altx_mark */
+ -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, uppper, step, page */
+ 0, 0, 0, /* descrLabels, descrValues, descrCount */
+ sp_object_layout_any_value_changed, /* callback */
+ tracker, /* unit_tracker */
+ SPIN_STEP, 3, 1); /* climb, digits, factor */
gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) );
contextActions->push_back( GTK_ACTION(eact) );
eact = create_adjustment_action(
- /* name= */ "YAction",
- /* label= */ C_("Select toolbar", "Y position"),
- /* shortLabel= */ C_("Select toolbar", "Y:"),
- /* tooltip= */ C_("Select toolbar", "Vertical coordinate of selection"),
- /* path= */ "/tools/select/Y",
- /* def(default) */ 0.0,
- /* focusTarget= */ GTK_WIDGET(desktop->canvas),
- /* dataKludge= */ G_OBJECT(spw),
- /* altx, altx_mark */ TRUE, "altx",
- /* lower, uppper, step, page */ -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
- /* descrLabels, descrValues, descrCount */ 0, 0, 0,
- /* callback= */ sp_object_layout_any_value_changed,
- /* unit_tracker= */ tracker,
- /* climb, digits, factor */ SPIN_STEP, 3, 1);
+ "YAction", /* name */
+ C_("Select toolbar", "Y position"), /* label */
+ C_("Select toolbar", "Y:"), /* shortLabel */
+ C_("Select toolbar", "Vertical coordinate of selection"), /* tooltip */
+ "/tools/select/Y", /* path */
+ 0.0, /* def(default) */
+ GTK_WIDGET(desktop->canvas), /* focusTarget */
+ G_OBJECT(spw), /* dataKludge */
+ TRUE, "altx", /* altx, altx_mark */
+ -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, uppper, step, page */
+ 0, 0, 0, /* descrLabels, descrValues, descrCount */
+ sp_object_layout_any_value_changed, /* callback */
+ tracker, /* unit_tracker */
+ SPIN_STEP, 3, 1); /* climb, digits, factor */
gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) );
contextActions->push_back( GTK_ACTION(eact) );
eact = create_adjustment_action(
- /* name= */ "WidthAction",
- /* label= */ C_("Select toolbar", "Width"),
- /* shortLabel= */ C_("Select toolbar", "W:"),
- /* tooltip= */ C_("Select toolbar", "Width of selection"),
- /* path= */ "/tools/select/width",
- /* def(default) */ 0.0,
- /* focusTarget= */ GTK_WIDGET(desktop->canvas),
- /* dataKludge= */ G_OBJECT(spw),
- /* altx, altx_mark */ TRUE, "altx",
- /* lower, uppper, step, page */ 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
- /* descrLabels, descrValues, descrCount */ 0, 0, 0,
- /* callback= */ sp_object_layout_any_value_changed,
- /* unit_tracker= */ tracker,
- /* climb, digits, factor */ SPIN_STEP, 3, 1);
+ "WidthAction", /* name */
+ C_("Select toolbar", "Width"), /* label */
+ C_("Select toolbar", "W:"), /* shortLabel */
+ C_("Select toolbar", "Width of selection"), /* tooltip */
+ "/tools/select/width", /* path */
+ 0.0, /* def(default) */
+ GTK_WIDGET(desktop->canvas), /* focusTarget */
+ G_OBJECT(spw), /* dataKludge */
+ TRUE, "altx", /* altx, altx_mark */
+ 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, uppper, step, page */
+ 0, 0, 0, /* descrLabels, descrValues, descrCount */
+ sp_object_layout_any_value_changed, /* callback */
+ tracker, /* unit_tracker */
+ SPIN_STEP, 3, 1); /* climb, digits, factor */
gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) );
contextActions->push_back( GTK_ACTION(eact) );
@@ -507,20 +507,21 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb
}
eact = create_adjustment_action(
- /* name= */ "HeightAction",
- /* label= */ C_("Select toolbar", "Height"),
- /* shortLabel= */ C_("Select toolbar", "H:"),
- /* tooltip= */ C_("Select toolbar", "Height of selection"),
- /* path= */ "/tools/select/height",
- /* def(default) */ 0.0,
- /* focusTarget= */ GTK_WIDGET(desktop->canvas),
- /* dataKludge= */ G_OBJECT(spw),
- /* altx, altx_mark */ TRUE, "altx",
- /* lower, uppper, step, page */ 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
- /* descrLabels, descrValues, descrCount */ 0, 0, 0,
- /* callback= */ sp_object_layout_any_value_changed,
- /* unit_tracker= */ tracker,
- /* climb, digits, factor */ SPIN_STEP, 3, 1);
+ "HeightAction", /* name */
+ C_("Select toolbar", "Height"), /* label */
+ C_("Select toolbar", "H:"), /* shortLabel */
+ C_("Select toolbar", "Height of selection"), /* tooltip */
+ "/tools/select/height", /* path */
+ 0.0, /* def(default) */
+ GTK_WIDGET(desktop->canvas), /* focusTarget */
+ G_OBJECT(spw), /* dataKludge */
+ TRUE, "altx", /* altx, altx_mark */
+ 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, uppper, step, page */
+ 0, 0, 0, /* descrLabels, descrValues, descrCount */
+ sp_object_layout_any_value_changed, /* callback */
+ tracker, /* unit_tracker */
+ SPIN_STEP, 3, 1); /* climb, digits, factor */
+
gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) );
contextActions->push_back( GTK_ACTION(eact) );
diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp
index 60e932338..8df80d2b6 100644
--- a/src/widgets/text-toolbar.cpp
+++ b/src/widgets/text-toolbar.cpp
@@ -62,9 +62,10 @@
using Inkscape::DocumentUndo;
using Inkscape::UI::ToolboxFactory;
using Inkscape::UI::PrefPusher;
-using Inkscape::UI::Widget::UnitTracker;
using Inkscape::Util::Unit;
+using Inkscape::Util::Quantity;
using Inkscape::Util::unit_table;
+using Inkscape::UI::Widget::UnitTracker;
//#define DEBUG_TEXT
@@ -509,48 +510,54 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl )
static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl )
{
- UnitTracker *tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(tbl, "tracker"));
-
- if ( !tracker || tracker->isUpdating() || g_object_get_data(tbl, "freeze")) {
- /*
- * When only units are being changed, don't treat changes
- * to adjuster values as object changes.
- * or quit if run by the _changed callbacks
- */
+ // quit if run by the _changed callbacks
+ if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
return;
}
g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
- // At the moment this handles only numerical values (i.e. no percent).
- // Set css line height.
- SPCSSAttr *css = sp_repr_css_attr_new ();
- Inkscape::CSSOStringStream osfs;
-
- gdouble value = gtk_adjustment_get_value(adj);
+ // Get user selected unit and save as preference
+ UnitTracker *tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(tbl, "tracker"));
Unit const *unit = tracker->getActiveUnit();
+ g_return_if_fail(unit != NULL);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
+
+ // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit so
+ // we can save it (allows us to adjust line height value when unit changes).
+ SPILength temp_length;
+ Inkscape::CSSOStringStream temp_stream;
+ temp_stream << 1 << unit->abbr;
+ temp_length.read(temp_stream.str().c_str());
+ prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit);
+ g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit));
- // Value can only be in px or percent or naked pc (e.g. 0.7 for 70%)
- if (unit->abbr != "%") {
- value = unit->convert(value, "px");
- unit = unit_table.getUnit("px");
- }
- osfs << value << unit->abbr;
+ // Set css line height.
+ SPCSSAttr *css = sp_repr_css_attr_new ();
+ Inkscape::CSSOStringStream osfs;
+ // We should handle unitless values as well as 'em' and 'ex'
+ if ((unit->abbr) == "em" || unit->abbr == "ex" || unit->abbr == "%") {
+ osfs << gtk_adjustment_get_value(adj) << unit->abbr;
+ } else {
+ // Inside SVG file, always use "px" for absolute units.
+ osfs << Quantity::convert(gtk_adjustment_get_value(adj), unit, "px") << "px";
+ }
sp_repr_css_set_property (css, "line-height", osfs.str().c_str());
+
// Apply line-height to selected objects.
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
sp_desktop_set_style (desktop, css, true, false);
- // Until deprecated sodipodi:linespacing purged:
+ // Only need to save for undo if a text item has been changed.
Inkscape::Selection *selection = desktop->getSelection();
bool modmade = false;
std::vector<SPItem*> itemlist=selection->itemList();
for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){
if (SP_IS_TEXT (*i)) {
- (*i)->getRepr()->setAttribute("sodipodi:linespacing", sp_repr_css_property (css, "line-height", NULL));
modmade = true;
}
}
@@ -576,6 +583,153 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl )
g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
}
+
+static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl )
+{
+ // quit if run by the _changed callbacks
+ if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
+ return;
+ }
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
+
+ // Get old saved unit
+ int old_unit = GPOINTER_TO_INT( g_object_get_data(tbl, "lineheight_unit"));
+
+ // Get user selected unit and save as preference
+ UnitTracker *tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(tbl, "tracker"));
+ Unit const *unit = tracker->getActiveUnit();
+ g_return_if_fail(unit != NULL);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
+ // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit.
+ SPILength temp_length;
+ Inkscape::CSSOStringStream temp_stream;
+ temp_stream << 1 << unit->abbr;
+ temp_length.read(temp_stream.str().c_str());
+ prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit);
+ g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit));
+
+ // Read current line height value
+ EgeAdjustmentAction *line_height_act =
+ reinterpret_cast<EgeAdjustmentAction *>(g_object_get_data(tbl, "TextLineHeightAction"));
+ GtkAdjustment *line_height_adj = ege_adjustment_action_get_adjustment( line_height_act );
+ double line_height = gtk_adjustment_get_value(line_height_adj);
+
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ Inkscape::Selection *selection = desktop->getSelection();
+ std::vector<SPItem*> itemlist=selection->itemList();
+
+ // Convert between units
+ if ((unit->abbr) == "em" && old_unit == SP_CSS_UNIT_EX) {
+ line_height *= 0.5;
+ } else if ((unit->abbr) == "ex" && old_unit == SP_CSS_UNIT_EM) {
+ line_height *= 2.0;
+ } else if ((unit->abbr) == "em" && old_unit == SP_CSS_UNIT_PERCENT) {
+ line_height /= 100.0;
+ } else if ((unit->abbr) == "%" && old_unit == SP_CSS_UNIT_EM) {
+ line_height *= 100;
+ } else if ((unit->abbr) == "ex" && old_unit == SP_CSS_UNIT_PERCENT) {
+ line_height /= 50.0;
+ } else if ((unit->abbr) == "%" && old_unit == SP_CSS_UNIT_EX) {
+ line_height *= 50;
+ } else if ((unit->abbr) == "%" || (unit->abbr) == "em" || (unit->abbr) == "ex") {
+ // Convert absolute to relative... for the moment use average font-size
+ double font_size = 0;
+ int count = 0;
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){
+ if (SP_IS_TEXT (*i)) {
+ font_size += (*i)->style->font_size.computed;
+ ++count;
+ }
+ }
+ if (count > 0) {
+ font_size /= count;
+ } else {
+ font_size = 20;
+ }
+ line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), "px");
+ if (font_size > 0) {
+ line_height /= font_size;
+ }
+ if ((unit->abbr) == "%") {
+ line_height *= 100;
+ } else if ((unit->abbr) == "ex") {
+ line_height *= 2;
+ }
+ } else if (old_unit==SP_CSS_UNIT_PERCENT || old_unit==SP_CSS_UNIT_EM || old_unit==SP_CSS_UNIT_EX) {
+ // Convert relative to absolute... for the moment use average font-size
+ double font_size = 0;
+ int count = 0;
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){
+ if (SP_IS_TEXT (*i)) {
+ font_size += (*i)->style->font_size.computed;
+ ++count;
+ }
+ }
+ if (count > 0) {
+ font_size /= count;
+ } else {
+ font_size = 20;
+ }
+ line_height *= font_size;
+ if (old_unit == SP_CSS_UNIT_PERCENT) {
+ line_height /= 100.0;
+ } else if (old_unit == SP_CSS_UNIT_EX) {
+ line_height /= 2.0;
+ }
+ line_height = Quantity::convert(line_height, "px", unit);
+ } else {
+ // Convert between different absolute units (only used in GUI)
+ line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), unit);
+ }
+
+ // Set css line height.
+ SPCSSAttr *css = sp_repr_css_attr_new ();
+ Inkscape::CSSOStringStream osfs;
+ // We should handle unitless values as well as 'em' and 'ex'
+ if ((unit->abbr) == "em" || unit->abbr == "ex" || unit->abbr == "%") {
+ osfs << line_height << unit->abbr;
+ } else {
+ osfs << Quantity::convert(line_height, unit, "px") << "px";
+ }
+ sp_repr_css_set_property (css, "line-height", osfs.str().c_str());
+
+ // Update GUI with line_height value.
+ gtk_adjustment_set_value(line_height_adj, line_height);
+
+ // Apply line-height to selected objects.
+ sp_desktop_set_style (desktop, css, true, false);
+
+ // Only need to save for undo if a text item has been changed.
+ bool modmade = false;
+ for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){
+ if (SP_IS_TEXT (*i)) {
+ modmade = true;
+ }
+ }
+
+ // Save for undo
+ if(modmade) {
+ DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE,
+ _("Text: Change line-height unit"));
+ }
+
+ // If no selected objects, set default.
+ SPStyle query(SP_ACTIVE_DOCUMENT);
+ int result_numbers =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ if (result_numbers == QUERY_STYLE_NOTHING)
+ {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->mergeStyle("/tools/text/style", css);
+ }
+
+ sp_repr_css_attr_unref (css);
+
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+}
+
+
static void sp_text_wordspacing_value_changed( GtkAdjustment *adj, GObject *tbl )
{
// quit if run by the _changed callbacks
@@ -1086,6 +1240,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/
{
activeButton = 3;
} else {
+ // This should take 'direction' into account
if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) activeButton = 0;
if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) activeButton = 1;
if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_END) activeButton = 2;
@@ -1093,36 +1248,59 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/
ege_select_one_action_set_active( textAlignAction, activeButton );
- // Line height (spacing)
+ // Line height (spacing) and line height unit
double height;
-
- Unit const *lh_unit;
- UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) );
-
+ int line_height_unit = -1;
if (query.line_height.normal) {
- lh_unit = unit_table.getUnit("%");
- height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL * 100;
- } else if (query.line_height.unit == SP_CSS_UNIT_PERCENT) {
- lh_unit = unit_table.getUnit("%");
- height = query.line_height.value * 100;
+ std::cout << " normal" << std::endl;
+ height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL;
+ line_height_unit = SP_CSS_UNIT_NONE;
} else {
- //Unit const *active = tracker->getActiveUnit();
- // This allows us to show the unit stored to the user, but right now
- // it's always px (because Tav said other units are broken/2016)
- lh_unit = unit_table.getUnit(query.line_height.unit);
- height = query.line_height.computed;
+ height = query.line_height.value;
+ line_height_unit = query.line_height.unit;
}
- // Set before value is set
- tracker->setActiveUnit(lh_unit);
+ switch (line_height_unit) {
+ case SP_CSS_UNIT_NONE:
+ // tracker can't show no unit... use 'em'
+ line_height_unit = SP_CSS_UNIT_EM;
+ case SP_CSS_UNIT_EM:
+ case SP_CSS_UNIT_EX:
+ break;
+ case SP_CSS_UNIT_PERCENT:
+ height *= 100.0; // Inkscape store % as fraction in .value
+ break;
+ case SP_CSS_UNIT_PX:
+ // If unit is set to 'px', use the preferred display unit (if absolute).
+ line_height_unit =
+ prefs->getInt("/tools/text/lineheight/display_unit", SP_CSS_UNIT_PT);
+ if (line_height_unit != SP_CSS_UNIT_EM &&
+ line_height_unit != SP_CSS_UNIT_EX &&
+ line_height_unit != SP_CSS_UNIT_PERCENT) {
+ height =
+ Quantity::convert(height, "px", sp_style_get_css_unit_string(line_height_unit));
+ } else {
+ line_height_unit = SP_CSS_UNIT_PX;
+ }
+ break;
+ default:
+ // If unit has been set by an external program to something other than 'px', use
+ // that unit. But height is average of computed values (px) so we need to convert
+ // back.
+ height =
+ Quantity::convert(height, "px", sp_style_get_css_unit_string(line_height_unit));
+ }
GtkAction* lineHeightAction = GTK_ACTION( g_object_get_data( tbl, "TextLineHeightAction" ) );
GtkAdjustment *lineHeightAdjustment =
ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( lineHeightAction ));
gtk_adjustment_set_value( lineHeightAdjustment, height );
- height = gtk_adjustment_get_value( lineHeightAdjustment );
-
+ UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) );
+ tracker->setActiveUnitByAbbr(sp_style_get_css_unit_string(line_height_unit));
+ // Save unit so we can do convertions between new/old units.
+ g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(line_height_unit));
+
// Word spacing
double wordSpacing;
if (query.word_spacing.normal) wordSpacing = 0.0;
@@ -1265,7 +1443,6 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/
#endif
g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
-
}
static void sp_text_toolbox_selection_modified(Inkscape::Selection *selection, guint /*flags*/, GObject *tbl)
@@ -1324,15 +1501,6 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p
static void text_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
-static void destroy_tracker( GObject* obj, gpointer /*user_data*/ )
-{
- UnitTracker *tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(obj, "tracker"));
- if ( tracker ) {
- delete tracker;
- g_object_set_data( obj, "tracker", 0 );
- }
-}
-
// Define all the "widgets" in the toolbar.
void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
@@ -1625,47 +1793,52 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_orientation_changed), holder );
}
+ /* Line height unit tracker */
+ UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR);
+ tracker->addUnit(unit_table.getUnit("%"));
+ tracker->addUnit(unit_table.getUnit("em"));
+ tracker->addUnit(unit_table.getUnit("ex"));
+ // tracker->addUnit(unit_table.getUnit("None"));
+ tracker->setActiveUnit(unit_table.getUnit("%"));
+ g_object_set_data( holder, "tracker", tracker );
+
/* Line height */
{
// Drop down menu
gchar const* labels[] = {_("Smaller spacing"), 0, 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, _("Larger spacing")};
gdouble values[] = { 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1,2, 1.3, 1.4, 1.5, 2.0};
- // Add the units menu.
- UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR);
- tracker->prependUnit(unit_table.getUnit("%"));
-
- g_object_set_data( holder, "tracker", tracker );
- g_signal_connect( holder, "destroy", G_CALLBACK(destroy_tracker), holder );
-
EgeAdjustmentAction *eact = create_adjustment_action(
"TextLineHeightAction", /* name */
_("Line Height"), /* label */
_("Line:"), /* short label */
- _("Spacing between baselines"), /* tooltip */
+ _("Spacing between baselines (times font size)"), /* tooltip */
"/tools/text/lineheight", /* preferences path */
- 125, /* default */
+ 0.0, /* default */
GTK_WIDGET(desktop->canvas), /* focusTarget */
holder, /* dataKludge */
FALSE, /* set alt-x keyboard shortcut? */
NULL, /* altx_mark */
- 0.0, 1e6, 1.0, 10.0, /* lower, upper, step (arrow up/down), page up/down */
+ 0.0, 1000.0, 1.0, 10.0, /* lower, upper, step (arrow up/down), page up/down */
labels, values, G_N_ELEMENTS(labels), /* drop down menu */
sp_text_lineheight_value_changed, /* callback */
- tracker, /* unit tracker */
- 1.0, /* step (used?) */
+ NULL, // tracker, /* unit tracker */
+ 0.1, /* step (used?) */
2, /* digits to show */
1.0 /* factor (multiplies default) */
);
+ //tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
g_object_set_data( holder, "TextLineHeightAction", eact );
g_object_set( G_OBJECT(eact), "iconId", "text_line_spacing", NULL );
+ }
- GtkAction* act = tracker->createAction( "TextLineHeightUnitAction", _("Units"), ("") );
+ /* Line height units */
+ {
+ GtkAction* act = tracker->createAction( "TextLineHeightUnitsAction", _("Units"), ("") );
gtk_action_group_add_action( mainActions, act );
- g_object_set_data( holder, "TextLineHeightUnitAction", act );
-
+ g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_lineheight_unit_changed), holder );
}
/* Word spacing */
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index f4d7ebf25..3389f82f9 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -516,7 +516,7 @@ static gchar const * ui_descr =
" <toolitem action='TextSubscriptAction' />"
" <separator />"
" <toolitem action='TextLineHeightAction' />"
- " <toolitem action='TextLineHeightUnitAction' />"
+ " <toolitem action='TextLineHeightUnitsAction' />"
" <toolitem action='TextLetterSpacingAction' />"
" <toolitem action='TextWordSpacingAction' />"
" <toolitem action='TextDxAction' />"
@@ -1126,7 +1126,7 @@ EgeAdjustmentAction * create_adjustment_action( gchar const *name,
if (unit_tracker) {
unit_tracker->addAdjustment(adj);
- }
+ }
// Using a cast just to make sure we pass in the right kind of function pointer
g_object_set( G_OBJECT(act), "tool-post", static_cast<EgeWidgetFixup>(sp_set_font_size_smaller), NULL );