summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthew Petroff <matthew@mpetroff.net>2013-09-20 17:09:19 +0000
committerMatthew Petroff <matthew@mpetroff.net>2013-09-20 17:09:19 +0000
commitcf74f053a081f6f4b460da9cd72afaab23d54d13 (patch)
tree427aa22ba3dcad9b55edb90522b5ab0208074e06 /src
parentUsing inkscape compact settings to save the icons.svg file (diff)
parentMerge from trunk. (diff)
downloadinkscape-cf74f053a081f6f4b460da9cd72afaab23d54d13.tar.gz
inkscape-cf74f053a081f6f4b460da9cd72afaab23d54d13.zip
Merge Google Summer of Code unit improvement.
(bzr r12554)
Diffstat (limited to 'src')
-rw-r--r--src/arc-context.cpp1
-rw-r--r--src/connector-context.cpp2
-rw-r--r--src/desktop.cpp10
-rw-r--r--src/document.cpp41
-rw-r--r--src/document.h5
-rw-r--r--src/draw-context.cpp1
-rw-r--r--src/dyna-draw-context.cpp4
-rw-r--r--src/ege-adjustment-action.cpp28
-rw-r--r--src/ege-adjustment-action.h14
-rw-r--r--src/extension/internal/cairo-renderer-pdf-out.cpp2
-rw-r--r--src/extension/internal/cairo-renderer.cpp8
-rw-r--r--src/extension/internal/emf-inout.cpp4
-rw-r--r--src/extension/internal/emf-print.cpp6
-rw-r--r--src/extension/internal/grid.cpp5
-rw-r--r--src/extension/internal/latex-pstricks.cpp8
-rw-r--r--src/extension/internal/latex-text-renderer.cpp4
-rw-r--r--src/extension/internal/odf.cpp3
-rw-r--r--src/extension/internal/pdfinput/pdf-parser.cpp6
-rw-r--r--src/extension/internal/pdfinput/svg-builder.cpp2
-rw-r--r--src/extension/internal/wmf-inout.cpp4
-rw-r--r--src/extension/internal/wmf-print.cpp4
-rw-r--r--src/file.cpp4
-rw-r--r--src/flood-context.cpp4
-rw-r--r--src/helper/pixbuf-ops.cpp4
-rw-r--r--src/helper/png-write.cpp3
-rw-r--r--src/inkview.cpp7
-rw-r--r--src/lpe-tool-context.cpp4
-rw-r--r--src/main.cpp8
-rw-r--r--src/object-snapper.cpp6
-rw-r--r--src/persp3d.cpp7
-rw-r--r--src/rect-context.cpp1
-rw-r--r--src/selection-chemistry.cpp10
-rw-r--r--src/shape-editor.cpp6
-rw-r--r--src/shape-editor.h3
-rw-r--r--src/sp-ellipse.cpp53
-rw-r--r--src/sp-ellipse.h1
-rw-r--r--src/sp-flowtext.cpp39
-rw-r--r--src/sp-flowtext.h7
-rw-r--r--src/sp-guide.cpp2
-rw-r--r--src/sp-item-group.cpp78
-rw-r--r--src/sp-item-group.h1
-rw-r--r--src/sp-item.cpp6
-rw-r--r--src/sp-root.h2
-rw-r--r--src/sp-spiral.cpp53
-rw-r--r--src/sp-spiral.h1
-rw-r--r--src/sp-star.cpp49
-rw-r--r--src/sp-star.h1
-rw-r--r--src/sp-text.cpp9
-rw-r--r--src/sp-text.h6
-rw-r--r--src/spiral-context.cpp1
-rw-r--r--src/star-context.cpp1
-rw-r--r--src/style.cpp30
-rw-r--r--src/svg-view-widget.cpp5
-rw-r--r--src/svg-view.cpp13
-rw-r--r--src/text-context.cpp1
-rw-r--r--src/ui/clipboard.cpp4
-rw-r--r--src/ui/dialog/aboutbox.cpp5
-rw-r--r--src/ui/dialog/document-properties.cpp63
-rw-r--r--src/ui/dialog/document-properties.h3
-rw-r--r--src/ui/dialog/export.cpp6
-rw-r--r--src/ui/dialog/print.cpp12
-rw-r--r--src/ui/dialog/text-edit.cpp2
-rw-r--r--src/ui/widget/page-sizer.cpp62
-rw-r--r--src/ui/widget/page-sizer.h8
-rw-r--r--src/ui/widget/spinbutton.cpp18
-rw-r--r--src/ui/widget/spinbutton.h5
-rw-r--r--src/util/expression-evaluator.cpp664
-rw-r--r--src/util/expression-evaluator.h112
-rw-r--r--src/util/units.cpp72
-rw-r--r--src/util/units.h24
-rw-r--r--src/widgets/calligraphy-toolbar.cpp16
-rw-r--r--src/widgets/connector-toolbar.cpp6
-rw-r--r--src/widgets/desktop-widget.cpp4
-rw-r--r--src/widgets/eraser-toolbar.cpp2
-rw-r--r--src/widgets/gradient-toolbar.cpp5
-rw-r--r--src/widgets/icon.cpp3
-rw-r--r--src/widgets/mesh-toolbar.cpp4
-rw-r--r--src/widgets/node-toolbar.cpp4
-rw-r--r--src/widgets/paintbucket-toolbar.cpp4
-rw-r--r--src/widgets/pencil-toolbar.cpp1
-rw-r--r--src/widgets/rect-toolbar.cpp19
-rw-r--r--src/widgets/select-toolbar.cpp5
-rw-r--r--src/widgets/spiral-toolbar.cpp2
-rw-r--r--src/widgets/spray-toolbar.cpp12
-rw-r--r--src/widgets/star-toolbar.cpp4
-rw-r--r--src/widgets/text-toolbar.cpp6
-rw-r--r--src/widgets/toolbox.cpp6
-rw-r--r--src/widgets/toolbox.h5
-rw-r--r--src/widgets/tweak-toolbar.cpp6
89 files changed, 1106 insertions, 656 deletions
diff --git a/src/arc-context.cpp b/src/arc-context.cpp
index 10e56f621..350df908b 100644
--- a/src/arc-context.cpp
+++ b/src/arc-context.cpp
@@ -451,6 +451,7 @@ void SPArcContext::finishItem() {
}
this->arc->updateRepr();
+ this->arc->doWriteTransform(this->arc->getRepr(), this->arc->transform, NULL, true);
desktop->canvas->endForcedFullRedraws();
diff --git a/src/connector-context.cpp b/src/connector-context.cpp
index c79c58125..3d6a4f28e 100644
--- a/src/connector-context.cpp
+++ b/src/connector-context.cpp
@@ -998,6 +998,8 @@ spcc_flush_white(SPConnectorContext *cc, SPCurve *gc)
cc->newconn->updateRepr();
}
+ cc->newconn->doWriteTransform(cc->newconn->getRepr(), cc->newconn->transform, NULL, true);
+
// Only set the selection after we are finished with creating the attributes of
// the connector. Otherwise, the selection change may alter the defaults for
// values like curvature in the connector context, preventing subsequent lookup
diff --git a/src/desktop.cpp b/src/desktop.cpp
index 69d83d8da..d19a99da6 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -242,7 +242,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid
// display rect and zoom are now handled in sp_desktop_widget_realize()
Geom::Rect const d(Geom::Point(0.0, 0.0),
- Geom::Point(document->getWidth(), document->getHeight()));
+ Geom::Point(document->getWidth().value("px"), document->getHeight().value("px")));
SP_CTRLRECT(page)->setRectangle(d);
SP_CTRLRECT(page_border)->setRectangle(d);
@@ -259,7 +259,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid
/* Connect event for page resize */
- _doc2dt[5] = document->getHeight();
+ _doc2dt[5] = document->getHeight().value("px");
sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt);
_modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this));
@@ -1108,7 +1108,7 @@ void
SPDesktop::zoom_page()
{
Geom::Rect d(Geom::Point(0, 0),
- Geom::Point(doc()->getWidth(), doc()->getHeight()));
+ Geom::Point(doc()->getWidth().value("px"), doc()->getHeight().value("px")));
if (d.minExtent() < 1.0) {
return;
@@ -1125,12 +1125,12 @@ SPDesktop::zoom_page_width()
{
Geom::Rect const a = get_display_area();
- if (doc()->getWidth() < 1.0) {
+ if (doc()->getWidth().value("px") < 1.0) {
return;
}
Geom::Rect d(Geom::Point(0, a.midpoint()[Geom::Y]),
- Geom::Point(doc()->getWidth(), a.midpoint()[Geom::Y]));
+ Geom::Point(doc()->getWidth().value("px"), a.midpoint()[Geom::Y]));
set_display_area(d, 10);
}
diff --git a/src/document.cpp b/src/document.cpp
index ec831745c..967d049c2 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -548,16 +548,20 @@ SPDocument *SPDocument::doUnref()
return NULL;
}
-gdouble SPDocument::getWidth() const
+Inkscape::Util::Quantity SPDocument::getWidth() const
{
- g_return_val_if_fail(this->priv != NULL, 0.0);
- g_return_val_if_fail(this->root != NULL, 0.0);
+ g_return_val_if_fail(this->priv != NULL, Inkscape::Util::Quantity(0.0, Inkscape::Util::Unit()));
+ g_return_val_if_fail(this->root != NULL, Inkscape::Util::Quantity(0.0, Inkscape::Util::Unit()));
- gdouble result = root->width.computed;
+ gdouble result = root->width.value;
+ SVGLength::Unit u = root->width.unit;
if (root->width.unit == SVGLength::PERCENT && root->viewBox_set) {
result = root->viewBox.width();
}
- return result;
+ if (u == SVGLength::NONE) {
+ u = SVGLength::PX;
+ }
+ return Inkscape::Util::Quantity(result, unit_table.getUnit(u));
}
void SPDocument::setWidth(const Inkscape::Util::Quantity &width)
@@ -584,16 +588,20 @@ void SPDocument::setWidth(const Inkscape::Util::Quantity &width)
root->updateRepr();
}
-gdouble SPDocument::getHeight() const
+Inkscape::Util::Quantity SPDocument::getHeight() const
{
- g_return_val_if_fail(this->priv != NULL, 0.0);
- g_return_val_if_fail(this->root != NULL, 0.0);
+ g_return_val_if_fail(this->priv != NULL, Inkscape::Util::Quantity(0.0, Inkscape::Util::Unit()));
+ g_return_val_if_fail(this->root != NULL, Inkscape::Util::Quantity(0.0, Inkscape::Util::Unit()));
- gdouble result = root->height.computed;
+ gdouble result = root->height.value;
+ SVGLength::Unit u = root->height.unit;
if (root->height.unit == SVGLength::PERCENT && root->viewBox_set) {
result = root->viewBox.height();
}
- return result;
+ if (u == SVGLength::NONE) {
+ u = SVGLength::PX;
+ }
+ return Inkscape::Util::Quantity(result, unit_table.getUnit(u));
}
void SPDocument::setHeight(const Inkscape::Util::Quantity &height)
@@ -620,9 +628,16 @@ void SPDocument::setHeight(const Inkscape::Util::Quantity &height)
root->updateRepr();
}
+void SPDocument::setViewBox(const Geom::Rect &viewBox)
+{
+ root->viewBox_set = true;
+ root->viewBox = viewBox;
+ root->updateRepr();
+}
+
Geom::Point SPDocument::getDimensions() const
{
- return Geom::Point(getWidth(), getHeight());
+ return Geom::Point(getWidth().value("px"), getHeight().value("px"));
}
Geom::OptRect SPDocument::preferredBounds() const
@@ -644,7 +659,7 @@ void SPDocument::fitToRect(Geom::Rect const &rect, bool with_margins)
double const w = rect.width();
double const h = rect.height();
- double const old_height = getHeight();
+ double const old_height = getHeight().value("px");
Inkscape::Util::Unit const px = unit_table.getUnit("px");
/* in px */
@@ -979,7 +994,7 @@ void SPDocument::setupViewport(SPItemCtx *ctx)
if (root->viewBox_set) { // if set, take from viewBox
ctx->viewport = root->viewBox;
} else { // as a last resort, set size to A4
- ctx->viewport = Geom::Rect::from_xywh(0, 0, 210 * Inkscape::Util::Quantity::convert(1, "mm", "px"), 297 * Inkscape::Util::Quantity::convert(1, "mm", "px"));
+ ctx->viewport = Geom::Rect::from_xywh(0, 0, Inkscape::Util::Quantity::convert(210, "mm", "px"), Inkscape::Util::Quantity::convert(297, "mm", "px"));
}
ctx->i2vp = Geom::identity();
}
diff --git a/src/document.h b/src/document.h
index 63332f431..948b5b867 100644
--- a/src/document.h
+++ b/src/document.h
@@ -227,12 +227,13 @@ public:
SPDocument *doRef();
SPDocument *doUnref();
- gdouble getWidth() const;
- gdouble getHeight() const;
+ Inkscape::Util::Quantity getWidth() const;
+ Inkscape::Util::Quantity getHeight() const;
Geom::Point getDimensions() const;
Geom::OptRect preferredBounds() const;
void setWidth(const Inkscape::Util::Quantity &width);
void setHeight(const Inkscape::Util::Quantity &height);
+ void setViewBox(const Geom::Rect &viewBox);
void requestModified();
gint ensureUpToDate();
bool addResource(const gchar *key, SPObject *object);
diff --git a/src/draw-context.cpp b/src/draw-context.cpp
index c33bb780c..09366526a 100644
--- a/src/draw-context.cpp
+++ b/src/draw-context.cpp
@@ -599,6 +599,7 @@ static void spdc_flush_white(SPDrawContext *dc, SPCurve *gc)
dc->selection->set(repr);
Inkscape::GC::release(repr);
item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ item->doWriteTransform(item->getRepr(), item->transform, NULL, true);
item->updateRepr();
}
diff --git a/src/dyna-draw-context.cpp b/src/dyna-draw-context.cpp
index 05ebc3a4a..3e35c0ac1 100644
--- a/src/dyna-draw-context.cpp
+++ b/src/dyna-draw-context.cpp
@@ -958,6 +958,10 @@ void SPDynaDrawContext::set_to_accumulated(bool unionize, bool subtract) {
sp_desktop_selection(desktop)->set(this->repr);
}
}
+
+ SPItem *item=SP_ITEM(desktop->doc()->getObjectByRepr(this->repr));
+ item->doWriteTransform(item->getRepr(), item->transform, NULL, true);
+
} else {
if (this->repr) {
sp_repr_unparent(this->repr);
diff --git a/src/ege-adjustment-action.cpp b/src/ege-adjustment-action.cpp
index 5a827096f..7f844ec4b 100644
--- a/src/ege-adjustment-action.cpp
+++ b/src/ege-adjustment-action.cpp
@@ -115,6 +115,7 @@ struct _EgeAdjustmentActionPrivate
gchar* appearance;
gchar* iconId;
Inkscape::IconSize iconSize;
+ Inkscape::UI::Widget::UnitTracker *unitTracker;
};
#define EGE_ADJUSTMENT_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), EGE_ADJUSTMENT_ACTION_TYPE, EgeAdjustmentActionPrivate ) )
@@ -128,7 +129,8 @@ enum {
PROP_TOOL_POST,
PROP_APPEARANCE,
PROP_ICON_ID,
- PROP_ICON_SIZE
+ PROP_ICON_SIZE,
+ PROP_UNIT_TRACKER
};
enum {
@@ -234,6 +236,13 @@ static void ege_adjustment_action_class_init( EgeAdjustmentActionClass* klass )
(int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
(GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+ g_object_class_install_property( objClass,
+ PROP_UNIT_TRACKER,
+ g_param_spec_pointer( "unit_tracker",
+ "Unit Tracker",
+ "The widget that keeps track of the unit",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
g_type_class_add_private( klass, sizeof(EgeAdjustmentActionClass) );
}
}
@@ -263,6 +272,7 @@ static void ege_adjustment_action_init( EgeAdjustmentAction* action )
action->private_data->appearance = 0;
action->private_data->iconId = 0;
action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
+ action->private_data->unitTracker = NULL;
}
static void ege_adjustment_action_finalize( GObject* object )
@@ -292,7 +302,8 @@ EgeAdjustmentAction* ege_adjustment_action_new( GtkAdjustment* adjustment,
const gchar *tooltip,
const gchar *stock_id,
gdouble climb_rate,
- guint digits )
+ guint digits,
+ Inkscape::UI::Widget::UnitTracker *unit_tracker )
{
GObject* obj = (GObject*)g_object_new( EGE_ADJUSTMENT_ACTION_TYPE,
"name", name,
@@ -302,6 +313,7 @@ EgeAdjustmentAction* ege_adjustment_action_new( GtkAdjustment* adjustment,
"adjustment", adjustment,
"climb-rate", climb_rate,
"digits", digits,
+ "unit_tracker", unit_tracker,
NULL );
EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( obj );
@@ -349,6 +361,10 @@ static void ege_adjustment_action_get_property( GObject* obj, guint propId, GVal
g_value_set_int( value, action->private_data->iconSize );
break;
+ case PROP_UNIT_TRACKER:
+ g_value_set_pointer( value, action->private_data->unitTracker );
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
}
@@ -450,6 +466,12 @@ void ege_adjustment_action_set_property( GObject* obj, guint propId, const GValu
}
break;
+ case PROP_UNIT_TRACKER:
+ {
+ action->private_data->unitTracker = (Inkscape::UI::Widget::UnitTracker*)g_value_get_pointer( value );
+ }
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
}
@@ -812,7 +834,7 @@ static GtkWidget* create_tool_item( GtkAction* action )
gtk_scale_button_set_icons( GTK_SCALE_BUTTON(spinbutton), floogles );
} else {
if ( gFactoryCb ) {
- spinbutton = gFactoryCb( act->private_data->adj, act->private_data->climbRate, act->private_data->digits );
+ spinbutton = gFactoryCb( act->private_data->adj, act->private_data->climbRate, act->private_data->digits, act->private_data->unitTracker );
} else {
spinbutton = gtk_spin_button_new( act->private_data->adj, act->private_data->climbRate, act->private_data->digits );
}
diff --git a/src/ege-adjustment-action.h b/src/ege-adjustment-action.h
index f63d4ed3e..590035eb3 100644
--- a/src/ege-adjustment-action.h
+++ b/src/ege-adjustment-action.h
@@ -63,6 +63,14 @@ typedef struct _EgeAdjustmentAction EgeAdjustmentAction;
typedef struct _EgeAdjustmentActionClass EgeAdjustmentActionClass;
typedef struct _EgeAdjustmentActionPrivate EgeAdjustmentActionPrivate;
+namespace Inkscape {
+ namespace UI {
+ namespace Widget {
+ class UnitTracker;
+ }
+ }
+}
+
/**
* Instance structure of EgeAdjustmentAction.
*/
@@ -95,7 +103,7 @@ GType ege_adjustment_action_get_type( void );
*/
/** Callback type for widgets creation factory */
-typedef GtkWidget* (*EgeCreateAdjWidgetCB)( GtkAdjustment *adjustment, gdouble climb_rate, guint digits );
+typedef GtkWidget* (*EgeCreateAdjWidgetCB)( GtkAdjustment *adjustment, gdouble climb_rate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker );
/**
* Sets a factory callback to be used to create the specific widget.
@@ -117,6 +125,7 @@ void ege_adjustment_action_set_compact_tool_factory( EgeCreateAdjWidgetCB factor
* @param stock_id Icon id to use.
* @param climb_rate Used for created widgets.
* @param digits Used for created widgets.
+ * @param unit_tracker Used to store unit.
*/
EgeAdjustmentAction* ege_adjustment_action_new( GtkAdjustment* adjustment,
const gchar *name,
@@ -124,7 +133,8 @@ EgeAdjustmentAction* ege_adjustment_action_new( GtkAdjustment* adjustment,
const gchar *tooltip,
const gchar *stock_id,
gdouble climb_rate,
- guint digits
+ guint digits,
+ Inkscape::UI::Widget::UnitTracker *unit_tracker
);
/**
* Returns a pointer to the GtkAdjustment represented by the given
diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp
index b9125582a..0c314a576 100644
--- a/src/extension/internal/cairo-renderer-pdf-out.cpp
+++ b/src/extension/internal/cairo-renderer-pdf-out.cpp
@@ -197,7 +197,7 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc,
float new_bleedmargin_px = 0.;
try {
- new_bleedmargin_px = mod->get_param_float("bleed") * Inkscape::Util::Quantity::convert(1, "mm", "px");
+ new_bleedmargin_px = Inkscape::Util::Quantity::convert(mod->get_param_float("bleed"), "mm", "px");
}
catch(...) {
g_warning("Parameter <bleed> might not exist");
diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp
index cace251cf..0a4c86f0b 100644
--- a/src/extension/internal/cairo-renderer.cpp
+++ b/src/extension/internal/cairo-renderer.cpp
@@ -463,8 +463,8 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx)
}
// The width and height of the bitmap in pixels
- unsigned width = ceil(bbox->width() * (res / Inkscape::Util::Quantity::convert(1, "in", "px")));
- unsigned height = ceil(bbox->height() * (res / Inkscape::Util::Quantity::convert(1, "in", "px")));
+ unsigned width = ceil(bbox->width() * Inkscape::Util::Quantity::convert(res, "px", "in"));
+ unsigned height = ceil(bbox->height() * Inkscape::Util::Quantity::convert(res, "px", "in"));
if (width == 0 || height == 0) return;
@@ -638,9 +638,9 @@ CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool page
Geom::Affine tp( Geom::Translate( bleedmargin_px, bleedmargin_px ) );
ctx->transform(tp);
} else {
- double high = doc->getHeight();
+ double high = doc->getHeight().value("px");
if (ctx->_vector_based_target)
- high *= Inkscape::Util::Quantity::convert(1, "px", "pt");
+ high = Inkscape::Util::Quantity::convert(high, "px", "pt");
// this transform translates the export drawing to a virtual page (0,0)-(width,height)
Geom::Affine tp(Geom::Translate(-d.left() * (ctx->_vector_based_target ? Inkscape::Util::Quantity::convert(1, "pt", "px") : 1.0),
diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp
index b185d3348..ab8a1ab64 100644
--- a/src/extension/internal/emf-inout.cpp
+++ b/src/extension/internal/emf-inout.cpp
@@ -1799,8 +1799,8 @@ std::cout << "BEFORE DRAW"
d->MMX = d->MM100InX / 100.0;
d->MMY = d->MM100InY / 100.0;
- d->PixelsOutX = d->MMX * Inkscape::Util::Quantity::convert(1, "mm", "px");
- d->PixelsOutY = d->MMY * Inkscape::Util::Quantity::convert(1, "mm", "px");
+ d->PixelsOutX = Inkscape::Util::Quantity::convert(d->MMX, "mm", "px");
+ d->PixelsOutY = Inkscape::Util::Quantity::convert(d->MMY, "mm", "px");
// Upper left corner, from header rclBounds, in device units, usually both 0, but not always
d->ulCornerInX = pEmr->rclBounds.left;
diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp
index 770257978..0df643130 100644
--- a/src/extension/internal/emf-print.cpp
+++ b/src/extension/internal/emf-print.cpp
@@ -138,8 +138,8 @@ unsigned int PrintEmf::begin(Inkscape::Extension::Print *mod, SPDocument *doc)
// width and height in px
- _width = doc->getWidth();
- _height = doc->getHeight();
+ _width = doc->getWidth().value("px");
+ _height = doc->getHeight().value("px");
// initialize a few global variables
hbrush = hbrushOld = hpen = 0;
@@ -243,7 +243,7 @@ unsigned int PrintEmf::begin(Inkscape::Extension::Print *mod, SPDocument *doc)
g_error("Fatal programming error in PrintEmf::begin at textcomment_set 1");
}
- snprintf(buff, sizeof(buff) - 1, "Drawing=%.1lfx%.1lfpx, %.1lfx%.1lfmm", _width, _height, dwInchesX * Inkscape::Util::Quantity::convert(1, "in", "mm"), dwInchesY * Inkscape::Util::Quantity::convert(1, "in", "mm"));
+ snprintf(buff, sizeof(buff) - 1, "Drawing=%.1lfx%.1lfpx, %.1lfx%.1lfmm", _width, _height, Inkscape::Util::Quantity::convert(dwInchesX, "in", "mm"), Inkscape::Util::Quantity::convert(dwInchesY, "in", "mm"));
rec = textcomment_set(buff);
if (!rec || emf_append((PU_ENHMETARECORD)rec, et, U_REC_FREE)) {
g_error("Fatal programming error in PrintEmf::begin at textcomment_set 1");
diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp
index 820d1c9d3..2f9d0ff25 100644
--- a/src/extension/internal/grid.cpp
+++ b/src/extension/internal/grid.cpp
@@ -35,6 +35,7 @@
#include "extension/effect.h"
#include "extension/system.h"
+#include "util/units.h"
#include "grid.h"
@@ -97,14 +98,14 @@ Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc
/* get page size */
SPDocument * doc = document->doc();
bounding_area = Geom::Rect( Geom::Point(0,0),
- Geom::Point(doc->getWidth(), doc->getHeight()) );
+ Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px")) );
} else {
Geom::OptRect bounds = selection->visualBounds();
if (bounds) {
bounding_area = *bounds;
}
- gdouble doc_height = (document->doc())->getHeight();
+ gdouble doc_height = (document->doc())->getHeight().value("px");
Geom::Rect temprec = Geom::Rect(Geom::Point(bounding_area.min()[Geom::X], doc_height - bounding_area.min()[Geom::Y]),
Geom::Point(bounding_area.max()[Geom::X], doc_height - bounding_area.max()[Geom::Y]));
diff --git a/src/extension/internal/latex-pstricks.cpp b/src/extension/internal/latex-pstricks.cpp
index 2ece1ba87..c8e8e2f2e 100644
--- a/src/extension/internal/latex-pstricks.cpp
+++ b/src/extension/internal/latex-pstricks.cpp
@@ -117,8 +117,8 @@ unsigned int PrintLatex::begin (Inkscape::Extension::Print *mod, SPDocument *doc
}
// width and height in pt
- _width = doc->getWidth() * Inkscape::Util::Quantity::convert(1, "px", "pt");
- _height = doc->getHeight() * Inkscape::Util::Quantity::convert(1, "px", "pt");
+ _width = doc->getWidth().value("pt");
+ _height = doc->getHeight().value("pt");
if (res >= 0) {
@@ -128,10 +128,10 @@ unsigned int PrintLatex::begin (Inkscape::Extension::Print *mod, SPDocument *doc
os << "\\psset{xunit=.5pt,yunit=.5pt,runit=.5pt}\n";
// from now on we can output px, but they will be treated as pt
- os << "\\begin{pspicture}(" << doc->getWidth() << "," << doc->getHeight() << ")\n";
+ os << "\\begin{pspicture}(" << doc->getWidth().value("px") << "," << doc->getHeight().value("px") << ")\n";
}
- m_tr_stack.push( Geom::Scale(1, -1) * Geom::Translate(0, doc->getHeight())); /// @fixme hardcoded doc2dt transform
+ m_tr_stack.push( Geom::Scale(1, -1) * Geom::Translate(0, doc->getHeight().value("px"))); /// @fixme hardcoded doc2dt transform
return fprintf(_stream, "%s", os.str().c_str());
}
diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp
index 7e6941232..398c9f061 100644
--- a/src/extension/internal/latex-text-renderer.cpp
+++ b/src/extension/internal/latex-text-renderer.cpp
@@ -633,7 +633,7 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, float bl
}
// flip y-axis
- push_transform( Geom::Scale(1,-1) * Geom::Translate(0, doc->getHeight()) ); /// @fixme hardcoded desktop transform!
+ push_transform( Geom::Scale(1,-1) * Geom::Translate(0, doc->getHeight().value("px")) ); /// @fixme hardcoded desktop transform!
// write the info to LaTeX
Inkscape::SVGOStringStream os;
@@ -642,7 +642,7 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, float bl
// scaling of the image when including it in LaTeX
os << " \\ifx\\svgwidth\\undefined%\n";
- os << " \\setlength{\\unitlength}{" << d.width() * Inkscape::Util::Quantity::convert(1, "px", "pt") << "bp}%\n"; // note: 'bp' is the Postscript pt unit in LaTeX, see LP bug #792384
+ os << " \\setlength{\\unitlength}{" << Inkscape::Util::Quantity::convert(d.width(), "px", "pt") << "bp}%\n"; // note: 'bp' is the Postscript pt unit in LaTeX, see LP bug #792384
os << " \\ifx\\svgscale\\undefined%\n";
os << " \\relax%\n";
os << " \\else%\n";
diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp
index a7c14387f..fcabcc4b2 100644
--- a/src/extension/internal/odf.cpp
+++ b/src/extension/internal/odf.cpp
@@ -75,6 +75,7 @@
#include "sp-flowtext.h"
#include "svg/svg.h"
#include "text-editing.h"
+#include "util/units.h"
//# DOM-specific includes
@@ -945,7 +946,7 @@ static Geom::Affine getODFTransform(const SPItem *item)
//### Get SVG-to-ODF transform
Geom::Affine tf (item->i2dt_affine());
//Flip Y into document coordinates
- double doc_height = SP_ACTIVE_DOCUMENT->getHeight();
+ double doc_height = SP_ACTIVE_DOCUMENT->getHeight().value("px");
Geom::Affine doc2dt_tf = Geom::Affine(Geom::Scale(1.0, -1.0)); /// @fixme hardcoded desktop transform
doc2dt_tf = doc2dt_tf * Geom::Affine(Geom::Translate(0, doc_height));
tf = tf * doc2dt_tf;
diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp
index 6e57f6278..7edb758fd 100644
--- a/src/extension/internal/pdfinput/pdf-parser.cpp
+++ b/src/extension/internal/pdfinput/pdf-parser.cpp
@@ -279,14 +279,14 @@ PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *bui
ignoreUndef = 0;
operatorHistory = NULL;
builder = builderA;
- builder->setDocumentSize(state->getPageWidth()*Inkscape::Util::Quantity::convert(1, "pt", "px"),
- state->getPageHeight()*Inkscape::Util::Quantity::convert(1, "pt", "px"));
+ builder->setDocumentSize(Inkscape::Util::Quantity::convert(state->getPageWidth(), "pt", "px"),
+ Inkscape::Util::Quantity::convert(state->getPageHeight(), "pt", "px"));
double *ctm = state->getCTM();
double scaledCTM[6];
for (int i = 0; i < 6; ++i) {
baseMatrix[i] = ctm[i];
- scaledCTM[i] = Inkscape::Util::Quantity::convert(1, "pt", "px") * ctm[i];
+ scaledCTM[i] = Inkscape::Util::Quantity::convert(ctm[i], "pt", "px");
}
saveState();
builder->setTransform((double*)&scaledCTM);
diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp
index a1a309a87..b3f15bbff 100644
--- a/src/extension/internal/pdfinput/svg-builder.cpp
+++ b/src/extension/internal/pdfinput/svg-builder.cpp
@@ -793,7 +793,7 @@ gchar *SvgBuilder::_createGradient(GfxShading *shading, double *matrix, bool for
Geom::Affine pat_matrix(matrix[0], matrix[1], matrix[2], matrix[3],
matrix[4], matrix[5]);
if ( !for_shading && _is_top_level ) {
- Geom::Affine flip(1.0, 0.0, 0.0, -1.0, 0.0, _height * Inkscape::Util::Quantity::convert(1, "px", "pt"));
+ Geom::Affine flip(1.0, 0.0, 0.0, -1.0, 0.0, Inkscape::Util::Quantity::convert(_height, "px", "pt"));
pat_matrix *= flip;
}
gchar *transform_text = sp_svg_transform_write(pat_matrix);
diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp
index 451d94c0e..373138187 100644
--- a/src/extension/internal/wmf-inout.cpp
+++ b/src/extension/internal/wmf-inout.cpp
@@ -1742,8 +1742,8 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK
tmp_outdef << " version=\"1.0\"\n";
tmp_outdef <<
- " width=\"" << d->PixelsOutX/ Inkscape::Util::Quantity::convert(1, "mm", "px") << "mm\"\n" <<
- " height=\"" << d->PixelsOutY/ Inkscape::Util::Quantity::convert(1, "mm", "px") << "mm\">\n";
+ " width=\"" << Inkscape::Util::Quantity::convert(d->PixelsOutX, "px", "mm") << "mm\"\n" <<
+ " height=\"" << Inkscape::Util::Quantity::convert(d->PixelsOutY, "px", "mm") << "mm\">\n";
*(d->outdef) += tmp_outdef.str().c_str();
*(d->outdef) += "<defs>"; // temporary end of header
diff --git a/src/extension/internal/wmf-print.cpp b/src/extension/internal/wmf-print.cpp
index 99262b109..cf0302b38 100644
--- a/src/extension/internal/wmf-print.cpp
+++ b/src/extension/internal/wmf-print.cpp
@@ -138,8 +138,8 @@ unsigned int PrintWmf::begin(Inkscape::Extension::Print *mod, SPDocument *doc)
// WMF header the only things that can be set are the page size in inches (w,h) and the dpi
// width and height in px
- _width = doc->getWidth();
- _height = doc->getHeight();
+ _width = doc->getWidth().value("px");
+ _height = doc->getHeight().value("px");
// initialize a few global variables
hbrush = hpen = 0;
diff --git a/src/file.cpp b/src/file.cpp
index 68e229e62..caea05d95 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -149,7 +149,7 @@ SPDesktop *sp_file_new(const Glib::ustring &templ)
// If the current desktop is empty, open the document there
doc->ensureUpToDate(); // TODO this will trigger broken link warnings, etc.
desktop->change_document(doc);
- doc->emitResizedSignal(doc->getWidth(), doc->getHeight());
+ doc->emitResizedSignal(doc->getWidth().value("px"), doc->getHeight().value("px"));
} else {
// create a whole new desktop and window
SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); // TODO this will trigger broken link warnings, etc.
@@ -291,7 +291,7 @@ bool sp_file_open(const Glib::ustring &uri,
// If the current desktop is empty, open the document there
doc->ensureUpToDate(); // TODO this will trigger broken link warnings, etc.
desktop->change_document(doc);
- doc->emitResizedSignal(doc->getWidth(), doc->getHeight());
+ doc->emitResizedSignal(doc->getWidth().value("px"), doc->getHeight().value("px"));
} else {
// create a whole new desktop and window
SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); // TODO this will trigger broken link warnings, etc.
diff --git a/src/flood-context.cpp b/src/flood-context.cpp
index 1f2a240ca..28aedba6e 100644
--- a/src/flood-context.cpp
+++ b/src/flood-context.cpp
@@ -764,7 +764,7 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even
unsigned int height = (int)ceil(screen.height() * zoom_scale * padding);
Geom::Point origin(screen.min()[Geom::X],
- document->getHeight() - screen.height() - screen.min()[Geom::Y]);
+ document->getHeight().value("px") - screen.height() - screen.min()[Geom::Y]);
origin[Geom::X] += (screen.width() * ((1 - padding) / 2));
origin[Geom::Y] += (screen.height() * ((1 - padding) / 2));
@@ -874,7 +874,7 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even
}
for (unsigned int i = 0; i < fill_points.size(); i++) {
- Geom::Point pw = Geom::Point(fill_points[i][Geom::X] / zoom_scale, document->getHeight() + (fill_points[i][Geom::Y] / zoom_scale)) * affine;
+ Geom::Point pw = Geom::Point(fill_points[i][Geom::X] / zoom_scale, document->getHeight().value("px") + (fill_points[i][Geom::Y] / zoom_scale)) * affine;
pw[Geom::X] = (int)MIN(width - 1, MAX(0, pw[Geom::X]));
pw[Geom::Y] = (int)MIN(height - 1, MAX(0, pw[Geom::Y]));
diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp
index 8e611d197..cd4f539ec 100644
--- a/src/helper/pixbuf-ops.cpp
+++ b/src/helper/pixbuf-ops.cpp
@@ -115,12 +115,12 @@ Inkscape::Pixbuf *sp_generate_internal_bitmap(SPDocument *doc, gchar const */*fi
double padding = 1.0;
Geom::Point origin(screen.min()[Geom::X],
- doc->getHeight() - screen[Geom::Y].extent() - screen.min()[Geom::Y]);
+ doc->getHeight().value("px") - screen[Geom::Y].extent() - screen.min()[Geom::Y]);
origin[Geom::X] = origin[Geom::X] + (screen[Geom::X].extent() * ((1 - padding) / 2));
origin[Geom::Y] = origin[Geom::Y] + (screen[Geom::Y].extent() * ((1 - padding) / 2));
- Geom::Scale scale( (xdpi / Inkscape::Util::Quantity::convert(1, "in", "px")), (ydpi / Inkscape::Util::Quantity::convert(1, "in", "px")));
+ Geom::Scale scale(Inkscape::Util::Quantity::convert(xdpi, "px", "in"), Inkscape::Util::Quantity::convert(ydpi, "px", "in"));
Geom::Affine affine = scale * Geom::Translate(-origin * scale);
/* Create ArenaItems and set transform */
diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp
index c43a207c8..b8b815b4c 100644
--- a/src/helper/png-write.cpp
+++ b/src/helper/png-write.cpp
@@ -34,6 +34,7 @@
#include "preferences.h"
#include "rdf.h"
#include "display/cairo-utils.h"
+#include "util/units.h"
/* This is an example of how to use libpng to read and write PNG files.
* The file libpng.txt is much more verbose then this. If you have not
@@ -415,7 +416,7 @@ ExportResult sp_export_png_file(SPDocument *doc, gchar const *filename,
doc->ensureUpToDate();
/* Calculate translation by transforming to document coordinates (flipping Y)*/
- Geom::Point translation = Geom::Point(-area[Geom::X][0], area[Geom::Y][1] - doc->getHeight());
+ Geom::Point translation = Geom::Point(-area[Geom::X][0], area[Geom::Y][1] - doc->getHeight().value("px"));
/* This calculation is only valid when assumed that (x0,y0)= area.corner(0) and (x1,y1) = area.corner(2)
* 1) a[0] * x0 + a[2] * y1 + a[4] = 0.0
diff --git a/src/inkview.cpp b/src/inkview.cpp
index fd7f6b608..e65638df6 100644
--- a/src/inkview.cpp
+++ b/src/inkview.cpp
@@ -54,6 +54,7 @@
#include "document.h"
#include "svg-view.h"
#include "svg-view-widget.h"
+#include "util/units.h"
#ifdef WITH_INKJAR
#include "io/inkjar.h"
@@ -308,8 +309,8 @@ main (int argc, const char **argv)
w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title( GTK_WINDOW(w), ss.doc->getName() );
gtk_window_set_default_size (GTK_WINDOW (w),
- MIN ((int)(ss.doc)->getWidth (), (int)gdk_screen_width () - 64),
- MIN ((int)(ss.doc)->getHeight (), (int)gdk_screen_height () - 64));
+ MIN ((int)(ss.doc)->getWidth().value("px"), (int)gdk_screen_width() - 64),
+ MIN ((int)(ss.doc)->getHeight().value("px"), (int)gdk_screen_height() - 64));
ss.window = w;
g_signal_connect (G_OBJECT (w), "delete_event", (GCallback) sp_svgview_main_delete, &ss);
@@ -318,7 +319,7 @@ main (int argc, const char **argv)
(ss.doc)->ensureUpToDate();
ss.view = sp_svg_view_widget_new (ss.doc);
(ss.doc)->doUnref ();
- SP_SVG_VIEW_WIDGET(ss.view)->setResize( false, ss.doc->getWidth(), ss.doc->getHeight() );
+ SP_SVG_VIEW_WIDGET(ss.view)->setResize( false, ss.doc->getWidth().value("px"), ss.doc->getHeight().value("px") );
gtk_widget_show (ss.view);
gtk_container_add (GTK_CONTAINER (w), ss.view);
diff --git a/src/lpe-tool-context.cpp b/src/lpe-tool-context.cpp
index 63707c1c5..14a536b7d 100644
--- a/src/lpe-tool-context.cpp
+++ b/src/lpe-tool-context.cpp
@@ -330,8 +330,8 @@ lpetool_context_switch_mode(SPLPEToolContext *lc, Inkscape::LivePathEffect::Effe
void
lpetool_get_limiting_bbox_corners(SPDocument *document, Geom::Point &A, Geom::Point &B) {
- Geom::Coord w = document->getWidth();
- Geom::Coord h = document->getHeight();
+ Geom::Coord w = document->getWidth().value("px");
+ Geom::Coord h = document->getHeight().value("px");
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
double ulx = prefs->getDouble("/tools/lpetool/bbox_upperleftx", 0);
diff --git a/src/main.cpp b/src/main.cpp
index 27346a230..9a365424c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1535,7 +1535,7 @@ static int sp_do_export_png(SPDocument *doc)
g_warning("Export width %lu out of range (1 - %lu). Nothing exported.", width, (unsigned long int)PNG_UINT_31_MAX);
return 1;
}
- dpi = (gdouble) width * Inkscape::Util::Quantity::convert(1, "in", "px") / area.width();
+ dpi = (gdouble) Inkscape::Util::Quantity::convert(width, "in", "px") / area.width();
}
if (sp_export_height) {
@@ -1545,15 +1545,15 @@ static int sp_do_export_png(SPDocument *doc)
g_warning("Export height %lu out of range (1 - %lu). Nothing exported.", height, (unsigned long int)PNG_UINT_31_MAX);
return 1;
}
- dpi = (gdouble) height * Inkscape::Util::Quantity::convert(1, "in", "px") / area.height();
+ dpi = (gdouble) Inkscape::Util::Quantity::convert(height, "in", "px") / area.height();
}
if (!sp_export_width) {
- width = (unsigned long int) (area.width() * dpi / Inkscape::Util::Quantity::convert(1, "in", "px") + 0.5);
+ width = (unsigned long int) (Inkscape::Util::Quantity::convert(area.width(), "px", "in") * dpi + 0.5);
}
if (!sp_export_height) {
- height = (unsigned long int) (area.height() * dpi / Inkscape::Util::Quantity::convert(1, "in", "px") + 0.5);
+ height = (unsigned long int) (Inkscape::Util::Quantity::convert(area.height(), "px", "in") * dpi + 0.5);
}
guint32 bgcolor = 0x00000000;
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index 77ba3040f..c5a3e1e88 100644
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
@@ -770,7 +770,7 @@ void Inkscape::ObjectSnapper::_clear_paths() const
Geom::PathVector* Inkscape::ObjectSnapper::_getBorderPathv() const
{
- Geom::Rect const border_rect = Geom::Rect(Geom::Point(0,0), Geom::Point((_snapmanager->getDocument())->getWidth(),(_snapmanager->getDocument())->getHeight()));
+ Geom::Rect const border_rect = Geom::Rect(Geom::Point(0,0), Geom::Point((_snapmanager->getDocument())->getWidth().value("px"),(_snapmanager->getDocument())->getHeight().value("px")));
return _getPathvFromRect(border_rect);
}
@@ -787,8 +787,8 @@ Geom::PathVector* Inkscape::ObjectSnapper::_getPathvFromRect(Geom::Rect const re
void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<SnapCandidatePoint> *points) const
{
- Geom::Coord w = (_snapmanager->getDocument())->getWidth();
- Geom::Coord h = (_snapmanager->getDocument())->getHeight();
+ Geom::Coord w = (_snapmanager->getDocument())->getWidth().value("px");
+ Geom::Coord h = (_snapmanager->getDocument())->getHeight().value("px");
points->push_back(SnapCandidatePoint(Geom::Point(0,0), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER));
points->push_back(SnapCandidatePoint(Geom::Point(0,h), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER));
points->push_back(SnapCandidatePoint(Geom::Point(w,h), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER));
diff --git a/src/persp3d.cpp b/src/persp3d.cpp
index a0e6f1c02..530da0799 100644
--- a/src/persp3d.cpp
+++ b/src/persp3d.cpp
@@ -24,6 +24,7 @@
#include "desktop-handles.h"
#include <glibmm/i18n.h>
#include "verbs.h"
+#include "util/units.h"
using Inkscape::DocumentUndo;
@@ -168,10 +169,10 @@ Persp3D *persp3d_create_xml_element(SPDocument *document, Persp3DImpl *dup) {//
repr = xml_doc->createElement("inkscape:perspective");
repr->setAttribute("sodipodi:type", "inkscape:persp3d");
- Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, document->getHeight()/2, 1.0);
+ Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, document->getHeight().value("px")/2, 1.0);
Proj::Pt2 proj_vp_y = Proj::Pt2 (0.0, 1000.0, 0.0);
- Proj::Pt2 proj_vp_z = Proj::Pt2 (document->getWidth(), document->getHeight()/2, 1.0);
- Proj::Pt2 proj_origin = Proj::Pt2 (document->getWidth()/2, document->getHeight()/3, 1.0);
+ Proj::Pt2 proj_vp_z = Proj::Pt2 (document->getWidth().value("px"), document->getHeight().value("px")/2, 1.0);
+ Proj::Pt2 proj_origin = Proj::Pt2 (document->getWidth().value("px")/2, document->getHeight().value("px")/3, 1.0);
if (dup) {
proj_vp_x = dup->tmat.column (Proj::X);
diff --git a/src/rect-context.cpp b/src/rect-context.cpp
index 8a7427928..599680190 100644
--- a/src/rect-context.cpp
+++ b/src/rect-context.cpp
@@ -478,6 +478,7 @@ void SPRectContext::finishItem() {
}
this->rect->updateRepr();
+ this->rect->doWriteTransform(this->rect->getRepr(), this->rect->transform, NULL, true);
this->desktop->canvas->endForcedFullRedraws();
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 91b99e3f4..0cb7123ae 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -2809,7 +2809,7 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply)
}
// calculate the transform to be applied to objects to move them to 0,0
- Geom::Point move_p = Geom::Point(0, doc->getHeight()) - *c;
+ Geom::Point move_p = Geom::Point(0, doc->getHeight().value("px")) - *c;
move_p[Geom::Y] = -move_p[Geom::Y];
Geom::Affine move = Geom::Affine(Geom::Translate(move_p));
@@ -3093,7 +3093,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply)
}
// calculate the transform to be applied to objects to move them to 0,0
- Geom::Point move_p = Geom::Point(0, doc->getHeight()) - (r->min() + Geom::Point(0, r->dimensions()[Geom::Y]));
+ Geom::Point move_p = Geom::Point(0, doc->getHeight().value("px")) - (r->min() + Geom::Point(0, r->dimensions()[Geom::Y]));
move_p[Geom::Y] = -move_p[Geom::Y];
Geom::Affine move = Geom::Affine(Geom::Translate(move_p));
@@ -3398,7 +3398,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop)
res = prefs_res;
} else if (0 < prefs_min) {
// If minsize is given, look up minimum bitmap size (default 250 pixels) and calculate resolution from it
- res = Inkscape::Util::Quantity::convert(1, "in", "px") * prefs_min / MIN(bbox->width(), bbox->height());
+ res = Inkscape::Util::Quantity::convert(prefs_min, "in", "px") / MIN(bbox->width(), bbox->height());
} else {
float hint_xdpi = 0, hint_ydpi = 0;
Glib::ustring hint_filename;
@@ -3419,8 +3419,8 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop)
}
// The width and height of the bitmap in pixels
- unsigned width = (unsigned) floor(bbox->width() * res / Inkscape::Util::Quantity::convert(1, "in", "px"));
- unsigned height =(unsigned) floor(bbox->height() * res / Inkscape::Util::Quantity::convert(1, "in", "px"));
+ unsigned width = (unsigned) floor(bbox->width() * Inkscape::Util::Quantity::convert(res, "px", "in"));
+ unsigned height =(unsigned) floor(bbox->height() * Inkscape::Util::Quantity::convert(res, "px", "in"));
// Find out if we have to run an external filter
gchar const *run = NULL;
diff --git a/src/shape-editor.cpp b/src/shape-editor.cpp
index 71018d89b..59d43f24c 100644
--- a/src/shape-editor.cpp
+++ b/src/shape-editor.cpp
@@ -35,6 +35,8 @@
using Inkscape::createKnotHolder;
+bool ShapeEditor::_blockSetItem = false;
+
ShapeEditor::ShapeEditor(SPDesktop *dt) {
this->desktop = dt;
this->knotholder = NULL;
@@ -169,6 +171,10 @@ static Inkscape::XML::NodeEventVector shapeeditor_repr_events = {
void ShapeEditor::set_item(SPItem *item, SubType type, bool keep_knotholder) {
+ if (_blockSetItem) {
+ return;
+ }
+
// this happens (and should only happen) when for an LPEItem having both knotholder and
// nodepath the knotholder is adapted; in this case we don't want to delete the knotholder
// since this freezes the handles
diff --git a/src/shape-editor.h b/src/shape-editor.h
index 206ff269b..9b3771fee 100644
--- a/src/shape-editor.h
+++ b/src/shape-editor.h
@@ -65,11 +65,14 @@ public:
void shapeeditor_event_attr_changed(gchar const *name);
bool knot_mouseover();
+
+ static void blockSetItem(bool b) {_blockSetItem = b;}
private:
bool has_knotholder ();
void reset_item (SubType type, bool keep_knotholder = true);
const SPItem *get_item (SubType type);
+ static bool _blockSetItem;
SPDesktop *desktop;
KnotHolder *knotholder;
diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp
index aad0336a7..cb39ef0ec 100644
--- a/src/sp-ellipse.cpp
+++ b/src/sp-ellipse.cpp
@@ -318,6 +318,59 @@ void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p,
}
}
+Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform)
+{
+ /* Calculate ellipse start in parent coords. */
+ Geom::Point pos( Geom::Point(this->cx.computed, this->cy.computed) * xform );
+
+ /* This function takes care of translation and scaling, we return whatever parts we can't
+ handle. */
+ Geom::Affine ret(Geom::Affine(xform).withoutTranslation());
+ gdouble const sw = hypot(ret[0], ret[1]);
+ gdouble const sh = hypot(ret[2], ret[3]);
+ if (sw > 1e-9) {
+ ret[0] /= sw;
+ ret[1] /= sw;
+ } else {
+ ret[0] = 1.0;
+ ret[1] = 0.0;
+ }
+ if (sh > 1e-9) {
+ ret[2] /= sh;
+ ret[3] /= sh;
+ } else {
+ ret[2] = 0.0;
+ ret[3] = 1.0;
+ }
+
+ if (this->rx._set) {
+ this->rx = this->rx.computed * sw;
+ }
+ if (this->ry._set) {
+ this->ry = this->ry.computed * sh;
+ }
+
+ /* Find start in item coords */
+ pos = pos * ret.inverse();
+ this->cx = pos[Geom::X];
+ this->cy = pos[Geom::Y];
+
+ this->set_shape();
+
+ // Adjust stroke width
+ this->adjust_stroke(sqrt(fabs(sw * sh)));
+
+ // Adjust pattern fill
+ this->adjust_pattern(xform * ret.inverse());
+
+ // Adjust gradient fill
+ this->adjust_gradient(xform * ret.inverse());
+
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
+
+ return ret;
+}
+
void
sp_genericellipse_normalize(SPGenericEllipse *ellipse)
{
diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h
index 2b1a00af7..b74beeae0 100644
--- a/src/sp-ellipse.h
+++ b/src/sp-ellipse.h
@@ -39,6 +39,7 @@ public:
virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
virtual void set_shape();
+ virtual Geom::Affine set_transform(Geom::Affine const& xform);
virtual void update_patheffect(bool write);
};
diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp
index 9d54ad92b..d46a644cf 100644
--- a/src/sp-flowtext.cpp
+++ b/src/sp-flowtext.cpp
@@ -28,6 +28,7 @@
#include "text-tag-attributes.h"
#include "text-chemistry.h"
#include "text-editing.h"
+#include "sp-text.h"
#include "livarot/Shape.h"
@@ -648,6 +649,44 @@ SPItem *create_flowtext_with_internal_frame (SPDesktop *desktop, Geom::Point p0,
return ft_item;
}
+Geom::Affine SPFlowtext::set_transform (Geom::Affine const &xform)
+{
+ if ((this->_optimizeScaledText && !xform.withoutTranslation().isNonzeroUniformScale())
+ || (!this->_optimizeScaledText && !xform.isNonzeroUniformScale())) {
+ this->_optimizeScaledText = false;
+ return xform;
+ }
+ this->_optimizeScaledText = false;
+
+ SPText *text = reinterpret_cast<SPText *>(this);
+
+ double const ex = xform.descrim();
+ if (ex == 0) {
+ return xform;
+ }
+
+ Geom::Affine ret(xform);
+ ret[0] /= ex;
+ ret[1] /= ex;
+ ret[2] /= ex;
+ ret[3] /= ex;
+
+ // Adjust font size
+ text->_adjustFontsizeRecursive (this, ex);
+
+ // Adjust stroke width
+ this->adjust_stroke_width_recursive (ex);
+
+ // Adjust pattern fill
+ this->adjust_pattern(xform * ret.inverse());
+
+ // Adjust gradient fill
+ this->adjust_gradient(xform * ret.inverse());
+
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG);
+
+ return ret;
+}
/*
Local Variables:
diff --git a/src/sp-flowtext.h b/src/sp-flowtext.h
index 1d3e30069..de328608f 100644
--- a/src/sp-flowtext.h
+++ b/src/sp-flowtext.h
@@ -43,6 +43,12 @@ public:
double par_indent;
+ bool _optimizeScaledText;
+
+ /** Optimize scaled flow text on next set_transform. */
+ void optimizeScaledText()
+ {_optimizeScaledText = true;}
+
private:
/** Recursively walks the xml tree adding tags and their contents. */
void _buildLayoutInput(SPObject *root, Shape const *exclusion_shape, std::list<Shape> *shapes, SPObject **pending_line_break_object);
@@ -58,6 +64,7 @@ public:
virtual void remove_child(Inkscape::XML::Node* child);
virtual void set(unsigned int key, const gchar* value);
+ virtual Geom::Affine set_transform(Geom::Affine const& xform);
virtual void update(SPCtx* ctx, unsigned int flags);
virtual void modified(unsigned int flags);
diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp
index 039edc90f..42a3b1ba7 100644
--- a/src/sp-guide.cpp
+++ b/src/sp-guide.cpp
@@ -287,7 +287,7 @@ sp_guide_create_guides_around_page(SPDesktop *dt) {
std::list<std::pair<Geom::Point, Geom::Point> > pts;
Geom::Point A(0, 0);
- Geom::Point C(doc->getWidth(), doc->getHeight());
+ Geom::Point C(doc->getWidth().value("px"), doc->getHeight().value("px"));
Geom::Point B(C[Geom::X], 0);
Geom::Point D(0, C[Geom::Y]);
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 5c176d2dc..720f6857a 100644
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
@@ -50,6 +50,9 @@
#include "sp-switch.h"
#include "sp-defs.h"
#include "verbs.h"
+#include "layer-model.h"
+#include "sp-textpath.h"
+#include "sp-flowtext.h"
using Inkscape::DocumentUndo;
@@ -644,6 +647,81 @@ void SPGroup::translateChildItems(Geom::Translate const &tr)
}
}
+// Recursively scale child items around a point
+void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p)
+{
+ if ( hasChildren() ) {
+ for (SPObject *o = firstChild() ; o ; o = o->getNext() ) {
+ if ( SP_IS_ITEM(o) ) {
+ if (SP_IS_GROUP(o) && !SP_IS_BOX3D(o)) {
+ SP_GROUP(o)->scaleChildItemsRec(sc, p);
+ } else {
+ SPItem *item = SP_ITEM(o);
+ Geom::OptRect bbox = item->desktopVisualBounds();
+ if (bbox) {
+ // Scale item
+ Geom::Translate const s(p);
+ Geom::Affine final = s.inverse() * sc * s;
+
+ Geom::Point old_center(0,0);
+ if (item->isCenterSet()) {
+ old_center = item->getCenter();
+ }
+
+ gchar const *conn_type = NULL;
+ if (SP_IS_TEXT_TEXTPATH(item)) {
+ SP_TEXT(item)->optimizeTextpathText();
+ } else if (SP_IS_FLOWTEXT(item)) {
+ SP_FLOWTEXT(item)->optimizeScaledText();
+ } else if (SP_IS_BOX3D(item)) {
+ // Force recalculation from perspective
+ box3d_position_set(SP_BOX3D(item));
+ } else if (item->getAttribute("inkscape:connector-type") != NULL
+ && (item->getAttribute("inkscape:connection-start") == NULL
+ || item->getAttribute("inkscape:connection-end") == NULL)) {
+ // Remove and store connector type for transform if disconnected
+ conn_type = item->getAttribute("inkscape:connector-type");
+ item->removeAttribute("inkscape:connector-type");
+ }
+
+ if (SP_IS_PERSP3D(item)) {
+ persp3d_apply_affine_transformation(SP_PERSP3D(item), final);
+ } else if ((SP_IS_TEXT_TEXTPATH(item) || SP_IS_FLOWTEXT(item)) && !item->transform.isIdentity()) {
+ // Save and reset current transform
+ Geom::Affine tmp(item->transform);
+ item->transform = Geom::Affine();
+ // Apply scale
+ item->set_i2d_affine(item->i2dt_affine() * sc);
+ item->doWriteTransform(item->getRepr(), item->transform, NULL, true);
+ // Scale translation and restore original transform
+ tmp[4] *= sc[0];
+ tmp[5] *= sc[1];
+ item->doWriteTransform(item->getRepr(), tmp, NULL, true);
+ } else if (SP_IS_USE(item)) {
+ // calculate the matrix we need to apply to the clone
+ // to cancel its induced transform from its original
+ Geom::Affine move = final.inverse() * item->transform * final;
+ item->doWriteTransform(item->getRepr(), move, &move, true);
+ } else {
+ item->set_i2d_affine(item->i2dt_affine() * final);
+ item->doWriteTransform(item->getRepr(), item->transform, NULL, true);
+ }
+
+ if (conn_type != NULL) {
+ item->setAttribute("inkscape:connector-type", conn_type);
+ }
+
+ if (item->isCenterSet() && !(final.isTranslation() || final.isIdentity())) {
+ item->setCenter(old_center * final);
+ item->updateRepr();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
gint SPGroup::getItemCount() {
gint len = 0;
for (SPObject *o = this->firstChild() ; o ; o = o->getNext() ) {
diff --git a/src/sp-item-group.h b/src/sp-item-group.h
index e6357ddcc..24c24abbd 100644
--- a/src/sp-item-group.h
+++ b/src/sp-item-group.h
@@ -52,6 +52,7 @@ public:
LayerMode layerDisplayMode(unsigned int display_key) const;
void setLayerDisplayMode(unsigned int display_key, LayerMode mode);
void translateChildItems(Geom::Translate const &tr);
+ void scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p);
gint getItemCount();
void _showChildren (Inkscape::Drawing &drawing, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags);
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index 154169e79..a91d0e741 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -73,6 +73,8 @@
#include "live_effects/effect.h"
#include "live_effects/lpeobject-reference.h"
+#include "util/units.h"
+
#define noSP_ITEM_DEBUG_IDLE
@@ -818,7 +820,7 @@ Geom::OptRect SPItem::desktopGeometricBounds() const
Geom::OptRect SPItem::desktopVisualBounds() const
{
/// @fixme hardcoded desktop transform
- Geom::Affine m = Geom::Scale(1, -1) * Geom::Translate(0, document->getHeight());
+ Geom::Affine m = Geom::Scale(1, -1) * Geom::Translate(0, document->getHeight().value("px"));
Geom::OptRect ret = documentVisualBounds();
if (ret) *ret *= m;
return ret;
@@ -1500,7 +1502,7 @@ Geom::Affine SPItem::i2dt_affine() const
// TODO temp code to prevent crashing on command-line launch:
ret = i2doc_affine()
* Geom::Scale(1, -1)
- * Geom::Translate(0, document->getHeight());
+ * Geom::Translate(0, document->getHeight().value("px"));
}
return ret;
}
diff --git a/src/sp-root.h b/src/sp-root.h
index a9f64a53b..47a37029d 100644
--- a/src/sp-root.h
+++ b/src/sp-root.h
@@ -41,7 +41,7 @@ public:
SVGLength height;
/* viewBox; */
- unsigned int viewBox_set : 1;
+ bool viewBox_set : true;
Geom::Rect viewBox;
/* preserveAspectRatio */
diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp
index ab7cc5c9d..e4bfb8c76 100644
--- a/src/sp-spiral.cpp
+++ b/src/sp-spiral.cpp
@@ -28,7 +28,6 @@
#include "sp-spiral.h"
-
#include "sp-factory.h"
namespace {
@@ -435,6 +434,58 @@ void SPSpiral::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape
}
/**
+ * Set spiral transform
+ */
+Geom::Affine SPSpiral::set_transform(Geom::Affine const &xform)
+{
+ // Only set transform with proportional scaling
+ if (!xform.withoutTranslation().isUniformScale()) {
+ return xform;
+ }
+
+ /* Calculate spiral start in parent coords. */
+ Geom::Point pos( Geom::Point(this->cx, this->cy) * xform );
+
+ /* This function takes care of translation and scaling, we return whatever parts we can't
+ handle. */
+ Geom::Affine ret(Geom::Affine(xform).withoutTranslation());
+ gdouble const s = hypot(ret[0], ret[1]);
+ if (s > 1e-9) {
+ ret[0] /= s;
+ ret[1] /= s;
+ ret[2] /= s;
+ ret[3] /= s;
+ } else {
+ ret[0] = 1.0;
+ ret[1] = 0.0;
+ ret[2] = 0.0;
+ ret[3] = 1.0;
+ }
+
+ this->rad *= s;
+
+ /* Find start in item coords */
+ pos = pos * ret.inverse();
+ this->cx = pos[Geom::X];
+ this->cy = pos[Geom::Y];
+
+ this->set_shape();
+
+ // Adjust stroke width
+ this->adjust_stroke(s);
+
+ // Adjust pattern fill
+ this->adjust_pattern(xform * ret.inverse());
+
+ // Adjust gradient fill
+ this->adjust_gradient(xform * ret.inverse());
+
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
+
+ return ret;
+}
+
+/**
* Return one of the points on the spiral.
*
* \param t specifies how far along the spiral.
diff --git a/src/sp-spiral.h b/src/sp-spiral.h
index c108eb2d0..a140d48f9 100644
--- a/src/sp-spiral.h
+++ b/src/sp-spiral.h
@@ -53,6 +53,7 @@ public:
/* Lowlevel interface */
void setPosition(gdouble cx, gdouble cy, gdouble exp, gdouble revo, gdouble rad, gdouble arg, gdouble t0);
+ virtual Geom::Affine set_transform(Geom::Affine const& xform);
Geom::Point getXY(gdouble t) const;
diff --git a/src/sp-star.cpp b/src/sp-star.cpp
index e5c5c7c25..bc3155caf 100644
--- a/src/sp-star.cpp
+++ b/src/sp-star.cpp
@@ -514,6 +514,55 @@ void SPStar::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::
}
}
+Geom::Affine SPStar::set_transform(Geom::Affine const &xform)
+{
+ // Only set transform with proportional scaling
+ if (!xform.withoutTranslation().isUniformScale()) {
+ return xform;
+ }
+
+ /* Calculate star start in parent coords. */
+ Geom::Point pos( this->center * xform );
+
+ /* This function takes care of translation and scaling, we return whatever parts we can't
+ handle. */
+ Geom::Affine ret(Geom::Affine(xform).withoutTranslation());
+ gdouble const s = hypot(ret[0], ret[1]);
+ if (s > 1e-9) {
+ ret[0] /= s;
+ ret[1] /= s;
+ ret[2] /= s;
+ ret[3] /= s;
+ } else {
+ ret[0] = 1.0;
+ ret[1] = 0.0;
+ ret[2] = 0.0;
+ ret[3] = 1.0;
+ }
+
+ this->r[0] *= s;
+ this->r[1] *= s;
+
+ /* Find start in item coords */
+ pos = pos * ret.inverse();
+ this->center = pos;
+
+ this->set_shape();
+
+ // Adjust stroke width
+ this->adjust_stroke(s);
+
+ // Adjust pattern fill
+ this->adjust_pattern(xform * ret.inverse());
+
+ // Adjust gradient fill
+ this->adjust_gradient(xform * ret.inverse());
+
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
+
+ return ret;
+}
+
/**
* sp_star_get_xy: Get X-Y value as item coordinate system
* @star: star item
diff --git a/src/sp-star.h b/src/sp-star.h
index 9ff85cdca..3096862cd 100644
--- a/src/sp-star.h
+++ b/src/sp-star.h
@@ -56,6 +56,7 @@ public:
virtual void update_patheffect(bool write);
virtual void set_shape();
+ virtual Geom::Affine set_transform(Geom::Affine const& xform);
};
void sp_star_position_set (SPStar *star, gint sides, Geom::Point center, gdouble r1, gdouble r2, gdouble arg1, gdouble arg2, bool isflat, double rounded, double randomized);
diff --git a/src/sp-text.cpp b/src/sp-text.cpp
index afd4e304e..927536dde 100644
--- a/src/sp-text.cpp
+++ b/src/sp-text.cpp
@@ -377,8 +377,13 @@ void SPText::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::
Geom::Affine SPText::set_transform(Geom::Affine const &xform) {
// we cannot optimize textpath because changing its fontsize will break its match to the path
- if (SP_IS_TEXT_TEXTPATH (this))
- return xform;
+ if (SP_IS_TEXT_TEXTPATH (this)) {
+ if (!this->_optimizeTextpathText) {
+ return xform;
+ } else {
+ this->_optimizeTextpathText = false;
+ }
+ }
/* This function takes care of scaling & translation only, we return whatever parts we can't
handle. */
diff --git a/src/sp-text.h b/src/sp-text.h
index 3a897a594..9b8afea6d 100644
--- a/src/sp-text.h
+++ b/src/sp-text.h
@@ -58,6 +58,8 @@ public:
/** discards the drawing objects representing this text. */
void _clearFlow(Inkscape::DrawingGroup *in_arena);
+ bool _optimizeTextpathText;
+
private:
/** Recursively walks the xml tree adding tags and their contents. The
non-trivial code does two things: firstly, it manages the positioning
@@ -67,6 +69,10 @@ private:
unsigned _buildLayoutInput(SPObject *root, Inkscape::Text::Layout::OptionalTextTagAttrs const &parent_optional_attrs, unsigned parent_attrs_offset, bool in_textpath);
public:
+ /** Optimize textpath text on next set_transform. */
+ void optimizeTextpathText()
+ {_optimizeTextpathText = true;}
+
virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
virtual void release();
virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref);
diff --git a/src/spiral-context.cpp b/src/spiral-context.cpp
index f841fe6d6..24a3ea6de 100644
--- a/src/spiral-context.cpp
+++ b/src/spiral-context.cpp
@@ -417,6 +417,7 @@ void SPSpiralContext::finishItem() {
spiral->set_shape();
spiral->updateRepr(SP_OBJECT_WRITE_EXT);
+ spiral->doWriteTransform(spiral->getRepr(), spiral->transform, NULL, true);
this->desktop->canvas->endForcedFullRedraws();
diff --git a/src/star-context.cpp b/src/star-context.cpp
index 1a04f823f..30112cbe9 100644
--- a/src/star-context.cpp
+++ b/src/star-context.cpp
@@ -443,6 +443,7 @@ void SPStarContext::finishItem() {
this->star->setCenter(this->center);
this->star->set_shape();
this->star->updateRepr(SP_OBJECT_WRITE_EXT);
+ this->star->doWriteTransform(this->star->getRepr(), this->star->transform, NULL, true);
desktop->canvas->endForcedFullRedraws();
diff --git a/src/style.cpp b/src/style.cpp
index e9cf22891..03c90bc09 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -2523,11 +2523,11 @@ sp_style_css_size_px_to_units(double size, int unit)
case SP_CSS_UNIT_NONE: unit_size = size; break;
case SP_CSS_UNIT_PX: unit_size = size; break;
- case SP_CSS_UNIT_PT: unit_size = size * Inkscape::Util::Quantity::convert(1, "px", "pt"); break;
- case SP_CSS_UNIT_PC: unit_size = size * (Inkscape::Util::Quantity::convert(1, "px", "pt") / Inkscape::Util::Quantity::convert(1, "pc", "pt")); break;
- case SP_CSS_UNIT_MM: unit_size = size * Inkscape::Util::Quantity::convert(1, "px", "mm"); break;
- case SP_CSS_UNIT_CM: unit_size = size * Inkscape::Util::Quantity::convert(1, "px", "cm"); break;
- case SP_CSS_UNIT_IN: unit_size = size * Inkscape::Util::Quantity::convert(1, "px", "in"); break;
+ case SP_CSS_UNIT_PT: unit_size = Inkscape::Util::Quantity::convert(size, "px", "pt"); break;
+ case SP_CSS_UNIT_PC: unit_size = Inkscape::Util::Quantity::convert(size, "px", "pc"); break;
+ case SP_CSS_UNIT_MM: unit_size = Inkscape::Util::Quantity::convert(size, "px", "mm"); break;
+ case SP_CSS_UNIT_CM: unit_size = Inkscape::Util::Quantity::convert(size, "px", "cm"); break;
+ case SP_CSS_UNIT_IN: unit_size = Inkscape::Util::Quantity::convert(size, "px", "in"); break;
case SP_CSS_UNIT_EM: unit_size = size / SP_CSS_FONT_SIZE_DEFAULT; break;
case SP_CSS_UNIT_EX: unit_size = size * 2.0 / SP_CSS_FONT_SIZE_DEFAULT ; break;
case SP_CSS_UNIT_PERCENT: unit_size = size * 100.0 / SP_CSS_FONT_SIZE_DEFAULT; break;
@@ -3530,19 +3530,19 @@ sp_style_read_ilength(SPILength *val, gchar const *str)
} else if (!strcmp(e, "pt")) {
/* Userspace / DEVICESCALE */
val->unit = SP_CSS_UNIT_PT;
- val->computed = value * Inkscape::Util::Quantity::convert(1, "pt", "px");
+ val->computed = Inkscape::Util::Quantity::convert(value, "pt", "px");
} else if (!strcmp(e, "pc")) {
val->unit = SP_CSS_UNIT_PC;
- val->computed = value * Inkscape::Util::Quantity::convert(1, "pc", "px");
+ val->computed = Inkscape::Util::Quantity::convert(value, "pc", "px");
} else if (!strcmp(e, "mm")) {
val->unit = SP_CSS_UNIT_MM;
- val->computed = value * Inkscape::Util::Quantity::convert(1, "mm", "px");
+ val->computed = Inkscape::Util::Quantity::convert(value, "mm", "px");
} else if (!strcmp(e, "cm")) {
val->unit = SP_CSS_UNIT_CM;
- val->computed = value * Inkscape::Util::Quantity::convert(1, "cm", "px");
+ val->computed = Inkscape::Util::Quantity::convert(value, "cm", "px");
} else if (!strcmp(e, "in")) {
val->unit = SP_CSS_UNIT_IN;
- val->computed = value * Inkscape::Util::Quantity::convert(1, "in", "px");
+ val->computed = Inkscape::Util::Quantity::convert(value, "in", "px");
} else if (!strcmp(e, "em")) {
/* EM square */
val->unit = SP_CSS_UNIT_EM;
@@ -4204,23 +4204,23 @@ sp_style_write_ilength(gchar *p, gint const len, gchar const *const key,
return g_strlcpy(p, os.str().c_str(), len);
break;
case SP_CSS_UNIT_PT:
- os << key << ":" << val->computed * Inkscape::Util::Quantity::convert(1, "px", "pt") << "pt;";
+ os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "pt") << "pt;";
return g_strlcpy(p, os.str().c_str(), len);
break;
case SP_CSS_UNIT_PC:
- os << key << ":" << val->computed * Inkscape::Util::Quantity::convert(1, "px", "pt") / 12.0 << "pc;";
+ os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "pc") << "pc;";
return g_strlcpy(p, os.str().c_str(), len);
break;
case SP_CSS_UNIT_MM:
- os << key << ":" << val->computed * Inkscape::Util::Quantity::convert(1, "px", "mm") << "mm;";
+ os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "mm") << "mm;";
return g_strlcpy(p, os.str().c_str(), len);
break;
case SP_CSS_UNIT_CM:
- os << key << ":" << val->computed * Inkscape::Util::Quantity::convert(1, "px", "cm") << "cm;";
+ os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "cm") << "cm;";
return g_strlcpy(p, os.str().c_str(), len);
break;
case SP_CSS_UNIT_IN:
- os << key << ":" << val->computed * Inkscape::Util::Quantity::convert(1, "px", "in") << "in;";
+ os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "in") << "in;";
return g_strlcpy(p, os.str().c_str(), len);
break;
case SP_CSS_UNIT_EM:
diff --git a/src/svg-view-widget.cpp b/src/svg-view-widget.cpp
index d392943e0..567156fec 100644
--- a/src/svg-view-widget.cpp
+++ b/src/svg-view-widget.cpp
@@ -21,6 +21,7 @@
#include "document.h"
#include "svg-view.h"
#include "svg-view-widget.h"
+#include "util/units.h"
static void sp_svg_view_widget_class_init (SPSVGSPViewWidgetClass *klass);
static void sp_svg_view_widget_init (SPSVGSPViewWidget *widget);
@@ -175,8 +176,8 @@ static void sp_svg_view_widget_size_request(GtkWidget *widget, GtkRequisition *r
gdouble width, height;
svgv = static_cast<SPSVGView*> (v);
- width = (v->doc())->getWidth () * svgv->_hscale;
- height = (v->doc())->getHeight () * svgv->_vscale;
+ width = (v->doc())->getWidth().value("px") * svgv->_hscale;
+ height = (v->doc())->getHeight().value("px") * svgv->_vscale;
if (width <= vw->maxwidth) {
hpol = GTK_POLICY_NEVER;
diff --git a/src/svg-view.cpp b/src/svg-view.cpp
index 7559cbb24..f52608420 100644
--- a/src/svg-view.cpp
+++ b/src/svg-view.cpp
@@ -20,6 +20,7 @@
#include "sp-item.h"
#include "svg-view.h"
#include "sp-root.h"
+#include "util/units.h"
SPSVGView::SPSVGView(SPCanvasGroup *parent)
{
@@ -71,16 +72,16 @@ void SPSVGView::doRescale(bool event)
if (!doc()) {
return;
}
- if (doc()->getWidth () < 1e-9) {
+ if (doc()->getWidth().value("px") < 1e-9) {
return;
}
- if (doc()->getHeight () < 1e-9) {
+ if (doc()->getHeight().value("px") < 1e-9) {
return;
}
if (_rescale) {
- _hscale = _width / doc()->getWidth ();
- _vscale = _height / doc()->getHeight ();
+ _hscale = _width / doc()->getWidth().value("px");
+ _vscale = _height / doc()->getHeight().value("px");
if (_keepaspect) {
if (_hscale > _vscale) {
_hscale = _vscale;
@@ -95,8 +96,8 @@ void SPSVGView::doRescale(bool event)
}
if (event) {
- emitResized (doc()->getWidth () * _hscale,
- doc()->getHeight () * _vscale);
+ emitResized (doc()->getWidth().value("px") * _hscale,
+ doc()->getHeight().value("px") * _vscale);
}
}
diff --git a/src/text-context.cpp b/src/text-context.cpp
index 502973633..10973b7aa 100644
--- a/src/text-context.cpp
+++ b/src/text-context.cpp
@@ -441,6 +441,7 @@ static void sp_text_context_setup_text(SPTextContext *tc)
text_item->transform = SP_ITEM(ec->desktop->currentLayer())->i2doc_affine().inverse();
text_item->updateRepr();
+ text_item->doWriteTransform(text_item->getRepr(), text_item->transform, NULL, true);
DocumentUndo::done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT,
_("Create text"));
}
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp
index 8a7812494..1d91a3b4d 100644
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
@@ -1087,8 +1087,8 @@ void ClipboardManagerImpl::_onGet(Gtk::SelectionData &sel, guint /*info*/)
Geom::Point origin (_clipboardSPDoc->getRoot()->x.computed, _clipboardSPDoc->getRoot()->y.computed);
Geom::Rect area = Geom::Rect(origin, origin + _clipboardSPDoc->getDimensions());
- unsigned long int width = (unsigned long int) (area.width() * dpi / Inkscape::Util::Quantity::convert(1, "in", "px") + 0.5);
- unsigned long int height = (unsigned long int) (area.height() * dpi / Inkscape::Util::Quantity::convert(1, "in", "px") + 0.5);
+ unsigned long int width = (unsigned long int) (Inkscape::Util::Quantity::convert(area.width(), "px", "in") * dpi + 0.5);
+ unsigned long int height = (unsigned long int) (Inkscape::Util::Quantity::convert(area.height(), "in", "px") * dpi + 0.5);
// read from namedview
Inkscape::XML::Node *nv = sp_repr_lookup_name (_clipboardSPDoc->rroot, "sodipodi:namedview");
diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp
index 6f1137e46..121773b6d 100644
--- a/src/ui/dialog/aboutbox.cpp
+++ b/src/ui/dialog/aboutbox.cpp
@@ -34,6 +34,7 @@
#include "svg-view-widget.h"
#include "sp-text.h"
#include "text-editing.h"
+#include "util/units.h"
#include "inkscape-version.h"
@@ -175,8 +176,8 @@ Gtk::Widget *build_splash_widget() {
GtkWidget *v=sp_svg_view_widget_new(doc);
- double width=doc->getWidth();
- double height=doc->getHeight();
+ double width=doc->getWidth().value("px");
+ double height=doc->getHeight().value("px");
doc->doUnref();
diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp
index 511e63d02..ec04f6d98 100644
--- a/src/ui/dialog/document-properties.cpp
+++ b/src/ui/dialog/document-properties.cpp
@@ -31,9 +31,12 @@
#include "inkscape.h"
#include "io/sys.h"
#include "preferences.h"
+#include "shape-editor.h"
#include "sp-namedview.h"
#include "sp-root.h"
#include "sp-script.h"
+#include "svg/stringstream.h"
+#include "tools-switch.h"
#include "ui/widget/color-picker.h"
#include "ui/widget/scalar-unit.h"
#include "ui/dialog/filedialog.h"
@@ -53,6 +56,8 @@
#include <gtkmm/stock.h>
#include <gtkmm/table.h>
+#include <2geom/transforms.h>
+
using std::pair;
namespace Inkscape {
@@ -168,6 +173,9 @@ DocumentProperties::DocumentProperties()
signalDocumentReplaced().connect(sigc::mem_fun(*this, &DocumentProperties::_handleDocumentReplaced));
signalActivateDesktop().connect(sigc::mem_fun(*this, &DocumentProperties::_handleActivateDesktop));
signalDeactiveDesktop().connect(sigc::mem_fun(*this, &DocumentProperties::_handleDeactivateDesktop));
+
+ _rum_deflt._changed_connection.block();
+ _rum_deflt.getUnitMenu()->signal_changed().connect(sigc::mem_fun(*this, &DocumentProperties::onDocUnitChange));
}
void DocumentProperties::init()
@@ -1432,9 +1440,17 @@ void DocumentProperties::update()
if (nv->doc_units)
_rum_deflt.setUnit (nv->doc_units->abbr);
- double const doc_w_px = sp_desktop_document(dt)->getWidth();
- double const doc_h_px = sp_desktop_document(dt)->getHeight();
- _page_sizer.setDim (doc_w_px, doc_h_px);
+ double const doc_w = sp_desktop_document(dt)->getRoot()->width.value;
+ Glib::ustring doc_w_unit = unit_table.getUnit(sp_desktop_document(dt)->getRoot()->width.unit).abbr;
+ if (doc_w_unit == "") {
+ doc_w_unit = "px";
+ }
+ double const doc_h = sp_desktop_document(dt)->getRoot()->height.value;
+ Glib::ustring doc_h_unit = unit_table.getUnit(sp_desktop_document(dt)->getRoot()->height.unit).abbr;
+ if (doc_h_unit == "") {
+ doc_h_unit = "px";
+ }
+ _page_sizer.setDim(Inkscape::Util::Quantity(doc_w, doc_w_unit), Inkscape::Util::Quantity(doc_h, doc_h_unit));
_page_sizer.updateFitMarginsUI(nv->getRepr());
//-----------------------------------------------------------guide page
@@ -1617,6 +1633,47 @@ void DocumentProperties::onRemoveGrid()
}
}
+/** Callback for document unit change. */
+void DocumentProperties::onDocUnitChange()
+{
+ SPDocument *doc = SP_ACTIVE_DOCUMENT;
+ Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr();
+ Inkscape::Util::Unit old_doc_unit = unit_table.getUnit("px");
+ if(repr->attribute("inkscape:document-units")) {
+ old_doc_unit = unit_table.getUnit(repr->attribute("inkscape:document-units"));
+ }
+ Inkscape::Util::Unit doc_unit = _rum_deflt.getUnit();
+
+ // Don't execute when change is being undone
+ if (!DocumentUndo::getUndoSensitive(doc)) {
+ return;
+ }
+
+ // Set document unit
+ Inkscape::SVGOStringStream os;
+ os << doc_unit.abbr;
+ repr->setAttribute("inkscape:document-units", os.str().c_str());
+
+ // Set viewBox
+ Inkscape::Util::Quantity width = doc->getWidth();
+ Inkscape::Util::Quantity height = doc->getHeight();
+ doc->setViewBox(Geom::Rect::from_xywh(0, 0, width.value(doc_unit), height.value(doc_unit)));
+
+ // TODO: Fix bug in nodes tool instead of switching away from it
+ if (tools_active(getDesktop()) == TOOLS_NODES) {
+ tools_switch(getDesktop(), TOOLS_SELECT);
+ }
+
+ // Scale and translate objects
+ gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit);
+ ShapeEditor::blockSetItem(true);
+ doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, doc->getHeight().value("px")));
+ ShapeEditor::blockSetItem(false);
+
+ doc->setModifiedSinceSave();
+
+ DocumentUndo::done(doc, SP_VERB_NONE, _("Changed document unit"));
+}
} // namespace Dialog
} // namespace UI
diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h
index 56fed30c4..e3ca91731 100644
--- a/src/ui/dialog/document-properties.h
+++ b/src/ui/dialog/document-properties.h
@@ -216,6 +216,9 @@ private:
// callback methods for buttons on grids page.
void onNewGrid();
void onRemoveGrid();
+
+ // callback for document unit change
+ void onDocUnitChange();
};
} // namespace Dialog
diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp
index 0b20c08a2..577793496 100644
--- a/src/ui/dialog/export.cpp
+++ b/src/ui/dialog/export.cpp
@@ -762,7 +762,7 @@ void Export::onAreaToggled ()
}
case SELECTION_PAGE:
bbox = Geom::Rect(Geom::Point(0.0, 0.0),
- Geom::Point(doc->getWidth(), doc->getHeight()));
+ Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px")));
// std::cout << "Using selection: PAGE" << std::endl;
key = SELECTION_PAGE;
@@ -1475,8 +1475,8 @@ void Export::detectSize() {
doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
Geom::Point x(0.0, 0.0);
- Geom::Point y(doc->getWidth(),
- doc->getHeight());
+ Geom::Point y(doc->getWidth().value("px"),
+ doc->getHeight().value("px"));
Geom::Rect bbox(x, y);
if (bbox_equal(bbox,current_bbox)) {
diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp
index 4c8c77f96..e6dae278b 100644
--- a/src/ui/dialog/print.cpp
+++ b/src/ui/dialog/print.cpp
@@ -49,8 +49,8 @@ static void draw_page(
if (junk->_tab->as_bitmap()) {
// Render as exported PNG
- gdouble width = (junk->_doc)->getWidth();
- gdouble height = (junk->_doc)->getHeight();
+ gdouble width = (junk->_doc)->getWidth().value("px");
+ gdouble height = (junk->_doc)->getHeight().value("px");
gdouble dpi = junk->_tab->bitmap_dpi();
std::string tmp_png;
std::string tmp_base = "inkscape-print-png-XXXXXX";
@@ -72,8 +72,8 @@ static void draw_page(
sp_export_png_file(junk->_doc, tmp_png.c_str(), 0.0, 0.0,
width, height,
- (unsigned long)(width * dpi / Inkscape::Util::Quantity::convert(1, "in", "px")),
- (unsigned long)(height * dpi / Inkscape::Util::Quantity::convert(1, "in", "px")),
+ (unsigned long)(Inkscape::Util::Quantity::convert(width, "px", "in") * dpi),
+ (unsigned long)(Inkscape::Util::Quantity::convert(height, "px", "in") * dpi),
dpi, dpi, bgcolor, NULL, NULL, true, NULL);
// This doesn't seem to work:
@@ -195,8 +195,8 @@ Print::Print(SPDocument *doc, SPItem *base) :
// set up paper size to match the document size
gtk_print_operation_set_unit (_printop, GTK_UNIT_POINTS);
GtkPageSetup *page_setup = gtk_page_setup_new();
- gdouble doc_width = _doc->getWidth() * Inkscape::Util::Quantity::convert(1, "px", "pt");
- gdouble doc_height = _doc->getHeight() * Inkscape::Util::Quantity::convert(1, "px", "pt");
+ gdouble doc_width = _doc->getWidth().value("pt");
+ gdouble doc_height = _doc->getHeight().value("pt");
GtkPaperSize *paper_size;
if (doc_width > doc_height) {
gtk_page_setup_set_orientation (page_setup, GTK_PAGE_ORIENTATION_LANDSCAPE);
diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index 4a25f723b..9124681a0 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -401,7 +401,7 @@ void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase)
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
- double pt_size = sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit) * Inkscape::Util::Quantity::convert(1, "px", "pt");
+ double pt_size = Inkscape::Util::Quantity::convert(sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit), "px", "pt");
// Pango font size is in 1024ths of a point
// C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE );
diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp
index 8287452d7..051937c43 100644
--- a/src/ui/widget/page-sizer.cpp
+++ b/src/ui/widget/page-sizer.cpp
@@ -442,6 +442,7 @@ PageSizer::init ()
_portrait_connection = _portraitButton.signal_toggled().connect (sigc::mem_fun (*this, &PageSizer::on_portrait));
_changedw_connection = _dimensionWidth.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
_changedh_connection = _dimensionHeight.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
+ _changedu_connection = _dimensionUnits.getUnitMenu()->signal_changed().connect (sigc::mem_fun (*this, &PageSizer::on_units_changed));
_fitPageButton.signal_clicked().connect(sigc::mem_fun(*this, &PageSizer::fire_fit_canvas_to_selection_or_drawing));
show_all_children();
@@ -454,11 +455,11 @@ PageSizer::init ()
* 'changeList' is true, then adjust the paperSizeList to show the closest
* standard page size.
*
- * \param w, h given in px
+ * \param w, h
* \param changeList whether to modify the paper size list
*/
void
-PageSizer::setDim (double w, double h, bool changeList)
+PageSizer::setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList)
{
static bool _called = false;
if (_called) {
@@ -475,12 +476,12 @@ PageSizer::setDim (double w, double h, bool changeList)
if (SP_ACTIVE_DESKTOP && !_widgetRegistry->isUpdating()) {
SPDocument *doc = sp_desktop_document(SP_ACTIVE_DESKTOP);
- double const old_height = doc->getHeight();
- doc->setWidth (Inkscape::Util::Quantity(w, "px"));
- doc->setHeight (Inkscape::Util::Quantity(h, "px"));
+ Inkscape::Util::Quantity const old_height = doc->getHeight();
+ doc->setWidth (w);
+ doc->setHeight (h);
// The origin for the user is in the lower left corner; this point should remain stationary when
// changing the page size. The SVG's origin however is in the upper left corner, so we must compensate for this
- Geom::Translate const vert_offset(Geom::Point(0, (old_height - h)));
+ Geom::Translate const vert_offset(Geom::Point(0, (old_height.value("px") - h.value("px"))));
doc->getRoot()->translateChildItems(vert_offset);
DocumentUndo::done(doc, SP_VERB_NONE, _("Set page size"));
}
@@ -503,9 +504,10 @@ PageSizer::setDim (double w, double h, bool changeList)
_paperSizeListSelection->select(row);
}
- Unit const& unit = _dimensionUnits.getUnit();
- _dimensionWidth.setValue (w / unit.factor);
- _dimensionHeight.setValue (h / unit.factor);
+ _dimensionWidth.setUnit(w.unit->abbr);
+ _dimensionWidth.setValue (w.quantity);
+ _dimensionHeight.setUnit(h.unit->abbr);
+ _dimensionHeight.setValue (h.quantity);
_paper_size_list_connection.unblock();
_landscape_connection.unblock();
@@ -547,12 +549,12 @@ PageSizer::updateFitMarginsUI(Inkscape::XML::Node *nv_repr)
* paperSizeListStore->children().end() if no such paper exists.
*/
Gtk::ListStore::iterator
-PageSizer::find_paper_size (double w, double h) const
+PageSizer::find_paper_size (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h) const
{
- double smaller = w;
- double larger = h;
+ double smaller = w.quantity;
+ double larger = h.quantity;
if ( h < w ) {
- smaller = h; larger = w;
+ smaller = h.quantity; larger = w.quantity;
}
g_return_val_if_fail(smaller <= larger, _paperSizeListStore->children().end());
@@ -562,8 +564,8 @@ PageSizer::find_paper_size (double w, double h) const
iter != _paperSizeTable.end() ; ++iter) {
PaperSize paper = iter->second;
Inkscape::Util::Unit const &i_unit = paper.unit;
- double smallX = Inkscape::Util::Quantity::convert(paper.smaller, i_unit, "px");
- double largeX = Inkscape::Util::Quantity::convert(paper.larger, i_unit, "px");
+ double smallX = Inkscape::Util::Quantity::convert(paper.smaller, i_unit, *w.unit);
+ double largeX = Inkscape::Util::Quantity::convert(paper.larger, i_unit, *w.unit);
g_return_val_if_fail(smallX <= largeX, _paperSizeListStore->children().end());
@@ -643,8 +645,8 @@ PageSizer::on_paper_size_list_changed()
return;
}
PaperSize paper = piter->second;
- double w = paper.smaller;
- double h = paper.larger;
+ Inkscape::Util::Quantity w = Inkscape::Util::Quantity(paper.smaller, paper.unit);
+ Inkscape::Util::Quantity h = Inkscape::Util::Quantity(paper.larger, paper.unit);
if (std::find(lscape_papers.begin(), lscape_papers.end(), paper.name.c_str()) != lscape_papers.end()) {
// enforce landscape mode if this is desired for the given page format
@@ -654,9 +656,6 @@ PageSizer::on_paper_size_list_changed()
_landscape = _landscapeButton.get_active();
}
- w = Inkscape::Util::Quantity::convert(w, paper.unit, "px");
- h = Inkscape::Util::Quantity::convert(h, paper.unit, "px");
-
if (_landscape)
setDim (h, w, false);
else
@@ -673,8 +672,8 @@ PageSizer::on_portrait()
{
if (!_portraitButton.get_active())
return;
- double w = _dimensionWidth.getValue ("px");
- double h = _dimensionHeight.getValue ("px");
+ Inkscape::Util::Quantity w = Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionWidth.getUnit());
+ Inkscape::Util::Quantity h = Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionHeight.getUnit());
if (h < w) {
setDim (h, w);
}
@@ -689,8 +688,8 @@ PageSizer::on_landscape()
{
if (!_landscapeButton.get_active())
return;
- double w = _dimensionWidth.getValue ("px");
- double h = _dimensionHeight.getValue ("px");
+ Inkscape::Util::Quantity w = Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionWidth.getUnit());
+ Inkscape::Util::Quantity h = Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionHeight.getUnit());
if (w < h) {
setDim (h, w);
}
@@ -703,11 +702,18 @@ void
PageSizer::on_value_changed()
{
if (_widgetRegistry->isUpdating()) return;
-
- setDim (_dimensionWidth.getValue("px"),
- _dimensionHeight.getValue("px"));
+ if (_unit != _dimensionUnits.getUnit().abbr) return;
+ setDim (Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionUnits.getUnit()),
+ Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit()));
+}
+void
+PageSizer::on_units_changed()
+{
+ if (_widgetRegistry->isUpdating()) return;
+ _unit = _dimensionUnits.getUnit().abbr;
+ setDim (Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionUnits.getUnit()),
+ Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit()));
}
-
} // namespace Widget
} // namespace UI
diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h
index 34ed7592d..95836a005 100644
--- a/src/ui/widget/page-sizer.h
+++ b/src/ui/widget/page-sizer.h
@@ -161,7 +161,7 @@ public:
* Set the page size to the given dimensions. If 'changeList' is
* true, then reset the paper size list to the closest match
*/
- void setDim (double w, double h, bool changeList=true);
+ void setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList=true);
/**
* Updates the scalar widgets for the fit margins. (Just changes the value
@@ -179,7 +179,7 @@ protected:
/**
* Find the closest standard paper size in the table, to the
*/
- Gtk::ListStore::iterator find_paper_size (double w, double h) const;
+ Gtk::ListStore::iterator find_paper_size (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h) const;
void fire_fit_canvas_to_selection_or_drawing();
@@ -252,13 +252,17 @@ protected:
//callback
void on_value_changed();
+ void on_units_changed();
sigc::connection _changedw_connection;
sigc::connection _changedh_connection;
+ sigc::connection _changedu_connection;
Registry *_widgetRegistry;
//### state - whether we are currently landscape or portrait
bool _landscape;
+
+ Glib::ustring _unit;
};
diff --git a/src/ui/widget/spinbutton.cpp b/src/ui/widget/spinbutton.cpp
index c107979a8..62c17f821 100644
--- a/src/ui/widget/spinbutton.cpp
+++ b/src/ui/widget/spinbutton.cpp
@@ -14,6 +14,7 @@
#include "spinbutton.h"
#include "unit-menu.h"
+#include "unit-tracker.h"
#include "util/expression-evaluator.h"
#include "event-context.h"
@@ -32,16 +33,23 @@ SpinButton::connect_signals() {
int SpinButton::on_input(double* newvalue)
{
try {
- Inkscape::Util::GimpEevlQuantity result;
- if (_unit_menu) {
- Unit unit = _unit_menu->getUnit();
- result = Inkscape::Util::gimp_eevl_evaluate (get_text().c_str(), &unit);
+ Inkscape::Util::EvaluatorQuantity result;
+ if (_unit_menu || _unit_tracker) {
+ Unit unit;
+ if (_unit_menu) {
+ unit = _unit_menu->getUnit();
+ } else {
+ unit = _unit_tracker->getActiveUnit();
+ }
+ Inkscape::Util::ExpressionEvaluator eval = Inkscape::Util::ExpressionEvaluator(get_text().c_str(), &unit);
+ result = eval.evaluate();
// check if output dimension corresponds to input unit
if (result.dimension != (unit.isAbsolute() ? 1 : 0) ) {
throw Inkscape::Util::EvaluatorException("Input dimensions do not match with parameter dimensions.","");
}
} else {
- result = Inkscape::Util::gimp_eevl_evaluate (get_text().c_str(), NULL);
+ Inkscape::Util::ExpressionEvaluator eval = Inkscape::Util::ExpressionEvaluator(get_text().c_str(), NULL);
+ result = eval.evaluate();
}
*newvalue = result.value;
diff --git a/src/ui/widget/spinbutton.h b/src/ui/widget/spinbutton.h
index fe5d699e7..c772fe2a2 100644
--- a/src/ui/widget/spinbutton.h
+++ b/src/ui/widget/spinbutton.h
@@ -25,6 +25,7 @@ namespace UI {
namespace Widget {
class UnitMenu;
+class UnitTracker;
/**
* SpinButton widget, that allows entry of simple math expressions (also units, when linked with UnitMenu),
@@ -50,14 +51,18 @@ public:
_unit_menu(NULL)
{
connect_signals();
+ _unit_tracker = NULL;
};
virtual ~SpinButton() {};
void setUnitMenu(UnitMenu* unit_menu) { _unit_menu = unit_menu; };
+
+ void addUnitTracker(UnitTracker* ut) { _unit_tracker = ut; };
protected:
UnitMenu *_unit_menu; /// Linked unit menu for unit conversion in entered expressions.
+ UnitTracker *_unit_tracker; // Linked unit tracker for unit conversion in entered expressions.
void connect_signals();
diff --git a/src/util/expression-evaluator.cpp b/src/util/expression-evaluator.cpp
index dc59c67f4..3b7e77c6c 100644
--- a/src/util/expression-evaluator.cpp
+++ b/src/util/expression-evaluator.cpp
@@ -6,6 +6,7 @@
* Copyright (C) 2008 Martin Nordholts <martinn@svn.gnome.org>
* Modified for Inkscape by Johan Engelen
* Copyright (C) 2011 Johan Engelen
+ * Copyright (C) 2013 Matthew Petroff
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,6 +28,7 @@
#include "util/expression-evaluator.h"
#include "util/units.h"
+#include <math.h>
#include <string.h>
using Inkscape::Util::unit_table;
@@ -34,495 +36,353 @@ using Inkscape::Util::unit_table;
namespace Inkscape {
namespace Util {
-enum
+EvaluatorQuantity::EvaluatorQuantity(double value, unsigned int dimension) :
+ value(value),
+ dimension(dimension)
{
- GIMP_EEVL_TOKEN_NUM = 30000,
- GIMP_EEVL_TOKEN_IDENTIFIER = 30001,
-
- GIMP_EEVL_TOKEN_ANY = 40000,
-
- GIMP_EEVL_TOKEN_END = 50000
-};
-
-typedef int GimpEevlTokenType;
-
-
-typedef struct
-{
- GimpEevlTokenType type;
-
- union
- {
- gdouble fl;
-
- struct
- {
- const gchar *c;
- gint size;
- };
-
- } value;
-
-} GimpEevlToken;
+}
-typedef struct
+EvaluatorToken::EvaluatorToken()
{
- const gchar *string;
- GimpEevlUnitResolverProc unit_resolver_proc;
- Unit *unit;
-
- GimpEevlToken current_token;
- const gchar *start_of_current_token;
-} GimpEevl;
+ type = 0;
+ value.fl = 0;
+}
-/** Unit Resolver...
- */
-static bool unitresolverproc (const gchar* identifier, GimpEevlQuantity *result, Unit* unit)
+ExpressionEvaluator::ExpressionEvaluator(const char *string, Unit *unit) :
+ string(string),
+ unit(unit)
{
- if (!unit) {
- result->value = 1;
- result->dimension = 1;
- return true;
- }else if (!identifier) {
- result->value = 1;
- result->dimension = unit->isAbsolute() ? 1 : 0;
- return true;
- } else if (unit_table.hasUnit(identifier)) {
- Unit identifier_unit = unit_table.getUnit(identifier);
-
- // Catch the case of zero or negative unit factors (error!)
- if (identifier_unit.factor < 0.0000001) {
- return false;
- }
-
- result->value = unit->factor / identifier_unit.factor;
- result->dimension = identifier_unit.isAbsolute() ? 1 : 0;
- return true;
- } else {
- return false;
- }
+ current_token.type = TOKEN_END;
+
+ // Preload symbol
+ parseNextToken();
}
-static void gimp_eevl_init (GimpEevl *eva,
- const gchar *string,
- GimpEevlUnitResolverProc unit_resolver_proc,
- Unit *unit);
-static GimpEevlQuantity gimp_eevl_complete (GimpEevl *eva);
-static GimpEevlQuantity gimp_eevl_expression (GimpEevl *eva);
-static GimpEevlQuantity gimp_eevl_term (GimpEevl *eva);
-static GimpEevlQuantity gimp_eevl_signed_factor (GimpEevl *eva);
-static GimpEevlQuantity gimp_eevl_factor (GimpEevl *eva);
-static gboolean gimp_eevl_accept (GimpEevl *eva,
- GimpEevlTokenType token_type,
- GimpEevlToken *consumed_token);
-static void gimp_eevl_lex (GimpEevl *eva);
-static void gimp_eevl_lex_accept_count (GimpEevl *eva,
- gint count,
- GimpEevlTokenType token_type);
-static void gimp_eevl_lex_accept_to (GimpEevl *eva,
- gchar *to,
- GimpEevlTokenType token_type);
-static void gimp_eevl_move_past_whitespace (GimpEevl *eva);
-static gboolean gimp_eevl_unit_identifier_start (gunichar c);
-static gboolean gimp_eevl_unit_identifier_continue (gunichar c);
-static gint gimp_eevl_unit_identifier_size (const gchar *s,
- gint start);
-static void gimp_eevl_expect (GimpEevl *eva,
- GimpEevlTokenType token_type,
- GimpEevlToken *value);
-static void gimp_eevl_error (GimpEevl *eva,
- const char *msg);
-
-
/**
* Evaluates the given arithmetic expression, along with an optional dimension
* analysis, and basic unit conversions.
*
- * @param string The NULL-terminated string to be evaluated.
- * @param unit_resolver_proc Unit resolver callback.
- *
* All units conversions factors are relative to some implicit
- * base-unit (which in GIMP is inches). This is also the unit of the
- * returned value.
+ * base-unit. This is also the unit of the returned value.
*
- * Returns: A #GimpEevlQuantity with a value given in the base unit along with
- * the order of the dimension (i.e. if the base unit is inches, a dimension
- * order of two menas in^2).
+ * Returns: An EvaluatorQuantity with a value given in the base unit along with
+ * the order of the dimension (e.g. if the base unit is inches, a dimension
+ * order of two means in^2).
*
* @return Result of evaluation.
* @throws Inkscape::Util::EvaluatorException There was a parse error.
**/
-GimpEevlQuantity
-gimp_eevl_evaluate (const gchar* string, Unit* unit)
+EvaluatorQuantity ExpressionEvaluator::evaluate()
{
- if (! g_utf8_validate (string, -1, NULL)) {
+ if (!g_utf8_validate(string, -1, NULL)) {
throw EvaluatorException("Invalid UTF8 string", NULL);
}
-
- GimpEevl eva;
- gimp_eevl_init (&eva, string, unitresolverproc, unit);
-
- return gimp_eevl_complete(&eva);
-}
-
-static void
-gimp_eevl_init (GimpEevl *eva,
- const gchar *string,
- GimpEevlUnitResolverProc unit_resolver_proc,
- Unit *unit)
-{
- eva->string = string;
- eva->unit_resolver_proc = unit_resolver_proc;
- eva->unit = unit;
-
- eva->current_token.type = GIMP_EEVL_TOKEN_END;
-
- /* Preload symbol... */
- gimp_eevl_lex (eva);
-}
-
-static GimpEevlQuantity
-gimp_eevl_complete (GimpEevl *eva)
-{
- GimpEevlQuantity result = {0, 0};
- GimpEevlQuantity default_unit_factor;
-
- /* Empty expression evaluates to 0 */
- if (gimp_eevl_accept (eva, GIMP_EEVL_TOKEN_END, NULL))
- return result;
-
- result = gimp_eevl_expression (eva);
-
- /* There should be nothing left to parse by now */
- gimp_eevl_expect (eva, GIMP_EEVL_TOKEN_END, 0);
-
- eva->unit_resolver_proc (NULL, &default_unit_factor, eva->unit);
-
- /* Entire expression is dimensionless, apply default unit if
- * applicable
- */
- if (result.dimension == 0 && default_unit_factor.dimension != 0)
- {
- result.value /= default_unit_factor.value;
- result.dimension = default_unit_factor.dimension;
+
+ EvaluatorQuantity result = EvaluatorQuantity();
+ EvaluatorQuantity default_unit_factor;
+
+ // Empty expression evaluates to 0
+ if (acceptToken(TOKEN_END, NULL)) {
+ return result;
+ }
+
+ result = evaluateExpression();
+
+ // There should be nothing left to parse by now
+ isExpected(TOKEN_END, 0);
+
+ resolveUnit(NULL, &default_unit_factor, unit);
+
+ // Entire expression is dimensionless, apply default unit if applicable
+ if ( result.dimension == 0 && default_unit_factor.dimension != 0 ) {
+ result.value /= default_unit_factor.value;
+ result.dimension = default_unit_factor.dimension;
}
- return result;
+ return result;
}
-static GimpEevlQuantity
-gimp_eevl_expression (GimpEevl *eva)
+EvaluatorQuantity ExpressionEvaluator::evaluateExpression()
{
- gboolean subtract;
- GimpEevlQuantity evaluated_terms;
-
- evaluated_terms = gimp_eevl_term (eva);
-
- /* continue evaluating terms, chained with + or -. */
- for (subtract = FALSE;
- gimp_eevl_accept (eva, '+', NULL) ||
- (subtract = gimp_eevl_accept (eva, '-', NULL));
- subtract = FALSE)
+ bool subtract;
+ EvaluatorQuantity evaluated_terms;
+
+ evaluated_terms = evaluateTerm();
+
+ // Continue evaluating terms, chained with + or -.
+ for (subtract = FALSE;
+ acceptToken('+', NULL) || (subtract = acceptToken('-', NULL));
+ subtract = FALSE)
{
- GimpEevlQuantity new_term = gimp_eevl_term (eva);
-
- /* If dimensions missmatch, attempt default unit assignent */
- if (new_term.dimension != evaluated_terms.dimension)
- {
- GimpEevlQuantity default_unit_factor;
-
- eva->unit_resolver_proc (NULL,
- &default_unit_factor,
- eva->unit);
-
- if (new_term.dimension == 0 &&
- evaluated_terms.dimension == default_unit_factor.dimension)
+ EvaluatorQuantity new_term = evaluateTerm();
+
+ // If dimensions mismatch, attempt default unit assignent
+ if ( new_term.dimension != evaluated_terms.dimension ) {
+ EvaluatorQuantity default_unit_factor;
+
+ resolveUnit(NULL, &default_unit_factor, unit);
+
+ if ( new_term.dimension == 0
+ && evaluated_terms.dimension == default_unit_factor.dimension )
{
- new_term.value /= default_unit_factor.value;
- new_term.dimension = default_unit_factor.dimension;
- }
- else if (evaluated_terms.dimension == 0 &&
- new_term.dimension == default_unit_factor.dimension)
+ new_term.value /= default_unit_factor.value;
+ new_term.dimension = default_unit_factor.dimension;
+ } else if ( evaluated_terms.dimension == 0
+ && new_term.dimension == default_unit_factor.dimension )
{
- evaluated_terms.value /= default_unit_factor.value;
- evaluated_terms.dimension = default_unit_factor.dimension;
- }
- else
- {
- gimp_eevl_error (eva, "Dimension missmatch during addition");
+ evaluated_terms.value /= default_unit_factor.value;
+ evaluated_terms.dimension = default_unit_factor.dimension;
+ } else {
+ throwError("Dimension mismatch during addition");
}
}
-
- evaluated_terms.value += (subtract ? -new_term.value : new_term.value);
+
+ evaluated_terms.value += (subtract ? -new_term.value : new_term.value);
}
-
- return evaluated_terms;
+
+ return evaluated_terms;
}
-static GimpEevlQuantity
-gimp_eevl_term (GimpEevl *eva)
+EvaluatorQuantity ExpressionEvaluator::evaluateTerm()
{
- gboolean division;
- GimpEevlQuantity evaluated_signed_factors;
-
- evaluated_signed_factors = gimp_eevl_signed_factor (eva);
-
- for (division = FALSE;
- gimp_eevl_accept (eva, '*', NULL) ||
- (division = gimp_eevl_accept (eva, '/', NULL));
- division = FALSE)
+ bool division;
+ EvaluatorQuantity evaluated_exp_terms = evaluateExpTerm();
+
+ for ( division = false;
+ acceptToken('*', NULL) || (division = acceptToken('/', NULL));
+ division = false )
{
- GimpEevlQuantity new_signed_factor = gimp_eevl_signed_factor (eva);
-
- if (division)
- {
- evaluated_signed_factors.value /= new_signed_factor.value;
- evaluated_signed_factors.dimension -= new_signed_factor.dimension;
-
- }
- else
- {
- evaluated_signed_factors.value *= new_signed_factor.value;
- evaluated_signed_factors.dimension += new_signed_factor.dimension;
+ EvaluatorQuantity new_exp_term = evaluateExpTerm();
+
+ if (division) {
+ evaluated_exp_terms.value /= new_exp_term.value;
+ evaluated_exp_terms.dimension -= new_exp_term.dimension;
+ } else {
+ evaluated_exp_terms.value *= new_exp_term.value;
+ evaluated_exp_terms.dimension += new_exp_term.dimension;
}
}
-
- return evaluated_signed_factors;
-}
-
-static GimpEevlQuantity
-gimp_eevl_signed_factor (GimpEevl *eva)
-{
- GimpEevlQuantity result;
- gboolean negate = FALSE;
-
- if (! gimp_eevl_accept (eva, '+', NULL))
- negate = gimp_eevl_accept (eva, '-', NULL);
-
- result = gimp_eevl_factor (eva);
-
- if (negate) result.value = -result.value;
-
- return result;
+
+ return evaluated_exp_terms;
}
-static GimpEevlQuantity
-gimp_eevl_factor (GimpEevl *eva)
+EvaluatorQuantity ExpressionEvaluator::evaluateExpTerm()
{
- GimpEevlQuantity evaluated_factor = { 0, 0 };
- GimpEevlToken consumed_token;
-
- if (gimp_eevl_accept (eva,
- GIMP_EEVL_TOKEN_NUM,
- &consumed_token))
- {
- evaluated_factor.value = consumed_token.value.fl;
- }
- else if (gimp_eevl_accept (eva, '(', NULL))
- {
- evaluated_factor = gimp_eevl_expression (eva);
- gimp_eevl_expect (eva, ')', 0);
- }
- else
- {
- gimp_eevl_error (eva, "Expected number or '('");
- }
-
- if (eva->current_token.type == GIMP_EEVL_TOKEN_IDENTIFIER)
- {
- gchar *identifier;
- GimpEevlQuantity result;
-
- gimp_eevl_accept (eva,
- GIMP_EEVL_TOKEN_ANY,
- &consumed_token);
-
- identifier = g_newa (gchar, consumed_token.value.size + 1);
-
- strncpy (identifier, consumed_token.value.c, consumed_token.value.size);
- identifier[consumed_token.value.size] = '\0';
-
- if (eva->unit_resolver_proc (identifier,
- &result,
- eva->unit))
- {
- evaluated_factor.value /= result.value;
- evaluated_factor.dimension += result.dimension;
- }
- else
- {
- gimp_eevl_error (eva, "Unit was not resolved");
+ EvaluatorQuantity evaluated_signed_factors = evaluateSignedFactor();
+
+ while(acceptToken('^', NULL)) {
+ EvaluatorQuantity new_signed_factor = evaluateSignedFactor();
+
+ if (new_signed_factor.dimension == 0) {
+ evaluated_signed_factors.value = pow(evaluated_signed_factors.value,
+ new_signed_factor.value);
+ evaluated_signed_factors.dimension *= new_signed_factor.value;
+ } else {
+ throwError("Unit in exponent");
}
}
-
- return evaluated_factor;
+
+ return evaluated_signed_factors;
}
-static gboolean
-gimp_eevl_accept (GimpEevl *eva,
- GimpEevlTokenType token_type,
- GimpEevlToken *consumed_token)
+EvaluatorQuantity ExpressionEvaluator::evaluateSignedFactor()
{
- gboolean existed = FALSE;
-
- if (token_type == eva->current_token.type ||
- token_type == GIMP_EEVL_TOKEN_ANY)
- {
- existed = TRUE;
-
- if (consumed_token)
- *consumed_token = eva->current_token;
-
- /* Parse next token */
- gimp_eevl_lex (eva);
+ EvaluatorQuantity result;
+ bool negate = FALSE;
+
+ if (!acceptToken('+', NULL)) {
+ negate = acceptToken ('-', NULL);
}
-
- return existed;
+
+ result = evaluateFactor();
+
+ if (negate) {
+ result.value = -result.value;
+ }
+
+ return result;
}
-static void
-gimp_eevl_lex (GimpEevl *eva)
+EvaluatorQuantity ExpressionEvaluator::evaluateFactor()
{
- const gchar *s;
-
- gimp_eevl_move_past_whitespace (eva);
- s = eva->string;
- eva->start_of_current_token = s;
-
- if (! s || s[0] == '\0')
- {
- /* We're all done */
- eva->current_token.type = GIMP_EEVL_TOKEN_END;
- }
- else if (s[0] == '+' || s[0] == '-')
- {
- /* Snatch these before the g_strtod() does, othewise they might
- * be used in a numeric conversion.
- */
- gimp_eevl_lex_accept_count (eva, 1, s[0]);
+ EvaluatorQuantity evaluated_factor = EvaluatorQuantity();
+ EvaluatorToken consumed_token = EvaluatorToken();
+
+ if (acceptToken(TOKEN_NUM, &consumed_token)) {
+ evaluated_factor.value = consumed_token.value.fl;
+ } else if (acceptToken('(', NULL)) {
+ evaluated_factor = evaluateExpression();
+ isExpected(')', 0);
+ } else {
+ throwError("Expected number or '('");
}
- else
- {
- /* Attempt to parse a numeric value */
- gchar *endptr = NULL;
- gdouble value = g_strtod (s, &endptr);
-
- if (endptr && endptr != s)
- {
- /* A numeric could be parsed, use it */
- eva->current_token.value.fl = value;
-
- gimp_eevl_lex_accept_to (eva, endptr, GIMP_EEVL_TOKEN_NUM);
+ if ( current_token.type == TOKEN_IDENTIFIER ) {
+ char *identifier;
+ EvaluatorQuantity result;
+
+ acceptToken(TOKEN_ANY, &consumed_token);
+
+ identifier = g_newa(char, consumed_token.value.size + 1);
+
+ strncpy(identifier, consumed_token.value.c, consumed_token.value.size);
+ identifier[consumed_token.value.size] = '\0';
+
+ if (resolveUnit(identifier, &result, unit)) {
+ evaluated_factor.value /= result.value;
+ evaluated_factor.dimension += result.dimension;
+ } else {
+ throwError("Unit was not resolved");
}
- else if (gimp_eevl_unit_identifier_start (s[0]))
- {
- /* Unit identifier */
- eva->current_token.value.c = s;
- eva->current_token.value.size = gimp_eevl_unit_identifier_size (s, 0);
+ }
+
+ return evaluated_factor;
+}
- gimp_eevl_lex_accept_count (eva,
- eva->current_token.value.size,
- GIMP_EEVL_TOKEN_IDENTIFIER);
- }
- else
- {
- /* Everything else is a single character token */
- gimp_eevl_lex_accept_count (eva, 1, s[0]);
+bool ExpressionEvaluator::acceptToken(TokenType token_type,
+ EvaluatorToken *consumed_token)
+{
+ bool existed = FALSE;
+
+ if ( token_type == current_token.type || token_type == TOKEN_ANY ) {
+ existed = TRUE;
+
+ if (consumed_token) {
+ *consumed_token = current_token;
}
+
+ // Parse next token
+ parseNextToken();
}
+
+ return existed;
}
-static void
-gimp_eevl_lex_accept_count (GimpEevl *eva,
- gint count,
- GimpEevlTokenType token_type)
+void ExpressionEvaluator::parseNextToken()
{
- eva->current_token.type = token_type;
- eva->string += count;
+ const char *s;
+
+ movePastWhiteSpace();
+ s = string;
+ start_of_current_token = s;
+
+ if ( !s || s[0] == '\0' ) {
+ // We're all done
+ current_token.type = TOKEN_END;
+ } else if ( s[0] == '+' || s[0] == '-' ) {
+ // Snatch these before the g_strtod() does, othewise they might
+ // be used in a numeric conversion.
+ acceptTokenCount(1, s[0]);
+ } else {
+ // Attempt to parse a numeric value
+ char *endptr = NULL;
+ gdouble value = g_strtod(s, &endptr);
+
+ if ( endptr && endptr != s ) {
+ // A numeric could be parsed, use it
+ current_token.value.fl = value;
+
+ current_token.type = TOKEN_NUM;
+ string = endptr;
+ } else if (isUnitIdentifierStart(s[0])) {
+ // Unit identifier
+ current_token.value.c = s;
+ current_token.value.size = getIdentifierSize(s, 0);
+
+ acceptTokenCount(current_token.value.size, TOKEN_IDENTIFIER);
+ } else {
+ // Everything else is a single character token
+ acceptTokenCount(1, s[0]);
+ }
+ }
}
-static void
-gimp_eevl_lex_accept_to (GimpEevl *eva,
- gchar *to,
- GimpEevlTokenType token_type)
+void ExpressionEvaluator::acceptTokenCount (int count, TokenType token_type)
{
- eva->current_token.type = token_type;
- eva->string = to;
+ current_token.type = token_type;
+ string += count;
}
-static void
-gimp_eevl_move_past_whitespace (GimpEevl *eva)
+void ExpressionEvaluator::isExpected(TokenType token_type,
+ EvaluatorToken *value)
{
- if (! eva->string)
- return;
-
- while (g_ascii_isspace (*eva->string))
- eva->string++;
+ if (!acceptToken(token_type, value)) {
+ throwError("Unexpected token");
+ }
}
-static gboolean
-gimp_eevl_unit_identifier_start (gunichar c)
+void ExpressionEvaluator::movePastWhiteSpace()
{
- return (g_unichar_isalpha (c) ||
- c == (gunichar) '%' ||
- c == (gunichar) '\'');
+ if (!string) {
+ return;
+ }
+
+ while (g_ascii_isspace(*string)) {
+ string++;
+ }
}
-static gboolean
-gimp_eevl_unit_identifier_continue (gunichar c)
+bool ExpressionEvaluator::isUnitIdentifierStart(gunichar c)
{
- return (gimp_eevl_unit_identifier_start (c) ||
- g_unichar_isdigit (c));
+ return (g_unichar_isalpha (c)
+ || c == (gunichar) '%'
+ || c == (gunichar) '\'');
}
/**
- * gimp_eevl_unit_identifier_size:
+ * getIdentifierSize:
* @s:
* @start:
*
* Returns: Size of identifier in bytes (not including NULL
* terminator).
**/
-static gint
-gimp_eevl_unit_identifier_size (const gchar *string,
- gint start_offset)
+int ExpressionEvaluator::getIdentifierSize(const char *string, int start_offset)
{
- const gchar *start = g_utf8_offset_to_pointer (string, start_offset);
- const gchar *s = start;
- gunichar c = g_utf8_get_char (s);
- gint length = 0;
-
- if (gimp_eevl_unit_identifier_start (c))
- {
- s = g_utf8_next_char (s);
- c = g_utf8_get_char (s);
- length++;
-
- while (gimp_eevl_unit_identifier_continue (c))
- {
- s = g_utf8_next_char (s);
- c = g_utf8_get_char (s);
- length++;
+ const char *start = g_utf8_offset_to_pointer(string, start_offset);
+ const char *s = start;
+ gunichar c = g_utf8_get_char(s);
+ int length = 0;
+
+ if (isUnitIdentifierStart(c)) {
+ s = g_utf8_next_char (s);
+ c = g_utf8_get_char (s);
+ length++;
+
+ while ( isUnitIdentifierStart (c) || g_unichar_isdigit (c) ) {
+ s = g_utf8_next_char(s);
+ c = g_utf8_get_char(s);
+ length++;
}
}
-
- return g_utf8_offset_to_pointer (start, length) - start;
+
+ return g_utf8_offset_to_pointer(start, length) - start;
}
-static void
-gimp_eevl_expect (GimpEevl *eva,
- GimpEevlTokenType token_type,
- GimpEevlToken *value)
+bool ExpressionEvaluator::resolveUnit (const char* identifier,
+ EvaluatorQuantity *result,
+ Unit* unit)
{
- if (! gimp_eevl_accept (eva, token_type, value))
- gimp_eevl_error (eva, "Unexpected token");
+ if (!unit) {
+ result->value = 1;
+ result->dimension = 1;
+ return true;
+ }else if (!identifier) {
+ result->value = 1;
+ result->dimension = unit->isAbsolute() ? 1 : 0;
+ return true;
+ } else if (unit_table.hasUnit(identifier)) {
+ Unit identifier_unit = unit_table.getUnit(identifier);
+ result->value = Quantity::convert(1, *unit, identifier_unit);
+ result->dimension = identifier_unit.isAbsolute() ? 1 : 0;
+ return true;
+ } else {
+ return false;
+ }
}
-static void
-gimp_eevl_error (GimpEevl *eva,
- const char *msg)
+void ExpressionEvaluator::throwError(const char *msg)
{
- throw EvaluatorException(msg, eva->start_of_current_token);
+ throw EvaluatorException(msg, start_of_current_token);
}
} // namespace Util
diff --git a/src/util/expression-evaluator.h b/src/util/expression-evaluator.h
index 4b1065268..6412dfea7 100644
--- a/src/util/expression-evaluator.h
+++ b/src/util/expression-evaluator.h
@@ -6,6 +6,7 @@
* Copyright (C) 2008-2009 Martin Nordholts <martinn@svn.gnome.org>
* Modified for Inkscape by Johan Engelen
* Copyright (C) 2011 Johan Engelen
+ * Copyright (C) 2013 Matthew Petroff
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,8 +23,8 @@
* <http://www.gnu.org/licenses/>.
*/
-#ifndef SEEN_GIMP_EEVL_H
-#define SEEN_GIMP_EEVL_H
+#ifndef INKSCAPE_UTIL_EXPRESSION_EVALUATOR_H
+#define INKSCAPE_UTIL_EXPRESSION_EVALUATOR_H
#include "util/units.h"
@@ -33,7 +34,7 @@
/**
* @file
- * Introducing eevl eva, the evaluator. A straightforward recursive
+ * Expression evaluator: A straightforward recursive
* descent parser, no fuss, no new dependencies. The lexer is hand
* coded, tedious, not extremely fast but works. It evaluates the
* expression as it goes along, and does not create a parse tree or
@@ -43,8 +44,8 @@
*
* It relies on external unit resolving through a callback and does
* elementary dimensionality constraint check (e.g. "2 mm + 3 px * 4
- * in" is an error, as L + L^2 is a missmatch). It uses g_strtod() for numeric
- * conversions and it's non-destructive in terms of the paramters, and
+ * in" is an error, as L + L^2 is a mismatch). It uses g_strtod() for numeric
+ * conversions and it's non-destructive in terms of the parameters, and
* it's reentrant.
*
* EBNF:
@@ -52,7 +53,9 @@
* expression ::= term { ('+' | '-') term }* |
* <empty string> ;
*
- * term ::= signed factor { ( '*' | '/' ) signed factor }* ;
+ * term ::= exponent { ( '*' | '/' ) exponent }* ;
+ *
+ * exponent ::= signed factor { '^' signed factor }* ;
*
* signed factor ::= ( '+' | '-' )? factor ;
*
@@ -79,37 +82,104 @@ namespace Util {
class Unit;
/**
-* GimpEevlQuantity:
-* @value: In reference units.
-* @dimension: in has a dimension of 1, in^2 has a dimension of 2 etc
-*/
-typedef struct
+ * EvaluatorQuantity:
+ * @param value In reference units.
+ * @param dimension mm has a dimension of 1, mm^2 has a dimension of 2, etc.
+ */
+class EvaluatorQuantity
{
+public:
+ EvaluatorQuantity(double value = 0, unsigned int dimension = 0);
+
double value;
- gint dimension;
-} GimpEevlQuantity;
+ unsigned int dimension;
+};
-typedef bool (* GimpEevlUnitResolverProc) (const gchar *identifier,
- GimpEevlQuantity *result,
- Unit* unit);
+/**
+ * TokenType
+ */
+enum {
+ TOKEN_NUM = 30000,
+ TOKEN_IDENTIFIER = 30001,
+ TOKEN_ANY = 40000,
+ TOKEN_END = 50000
+};
+typedef int TokenType;
-GimpEevlQuantity gimp_eevl_evaluate (const gchar* string, Unit* unit = NULL);
+/**
+ * EvaluatorToken
+ */
+class EvaluatorToken
+{
+public:
+ EvaluatorToken();
+
+ TokenType type;
+
+ union {
+ double fl;
+ struct {
+ const char *c;
+ int size;
+ };
+ } value;
+};
+
+/**
+ * ExpressionEvaluator
+ * @param string NULL terminated input string to evaluate
+ * @param unit Unit output should be in
+ */
+class ExpressionEvaluator
+{
+public:
+ ExpressionEvaluator(const char *string, Unit *unit = NULL);
+
+ EvaluatorQuantity evaluate();
+
+private:
+ const char *string;
+ Unit *unit;
+
+ EvaluatorToken current_token;
+ const char *start_of_current_token;
+
+ EvaluatorQuantity evaluateExpression();
+ EvaluatorQuantity evaluateTerm();
+ EvaluatorQuantity evaluateExpTerm();
+ EvaluatorQuantity evaluateSignedFactor();
+ EvaluatorQuantity evaluateFactor();
+
+ bool acceptToken(TokenType token_type, EvaluatorToken *consumed_token);
+ void parseNextToken();
+ void acceptTokenCount(int count, TokenType token_type);
+ void isExpected(TokenType token_type, EvaluatorToken *value);
+
+ void movePastWhiteSpace();
+
+ static bool isUnitIdentifierStart(gunichar c);
+ static int getIdentifierSize(const char *s, int start);
+
+ static bool resolveUnit(const char *identifier, EvaluatorQuantity *result, Unit *unit);
+
+ void throwError(const char *msg);
+};
/**
* Special exception class for the expression evaluator.
*/
class EvaluatorException : public std::exception {
public:
- EvaluatorException(const char * message, const char *at_position) {
+ EvaluatorException(const char *message, const char *at_position) {
std::ostringstream os;
- const char* token = at_position ? at_position : "<End of input>";
+ const char *token = at_position ? at_position : "<End of input>";
os << "Expression evaluator error: " << message << " at '" << token << "'";
msgstr = os.str();
}
virtual ~EvaluatorException() throw() {} // necessary to destroy the string object!!!
- virtual const char* what() const throw () {
+ virtual const char *what() const throw () {
return msgstr.c_str();
}
protected:
@@ -119,4 +189,4 @@ protected:
}
}
-#endif // SEEN_GIMP_EEVL_H
+#endif // INKSCAPE_UTIL_EXPRESSION_EVALUATOR_H
diff --git a/src/util/units.cpp b/src/util/units.cpp
index 3fdd77916..e5c6f74fb 100644
--- a/src/util/units.cpp
+++ b/src/util/units.cpp
@@ -114,6 +114,7 @@ Unit::Unit(UnitType type,
abbr(abbr),
description(description)
{
+ g_return_if_fail(factor <= 0);
}
void Unit::clear()
@@ -166,25 +167,25 @@ bool operator!= (const Unit &u1, const Unit &u2)
int Unit::svgUnit() const
{
if (!abbr.compare("px"))
- return 1;
+ return SVGLength::PX;
if (!abbr.compare("pt"))
- return 2;
+ return SVGLength::PT;
if (!abbr.compare("pc"))
- return 3;
+ return SVGLength::PC;
if (!abbr.compare("mm"))
- return 4;
+ return SVGLength::MM;
if (!abbr.compare("cm"))
- return 5;
+ return SVGLength::CM;
if (!abbr.compare("in"))
- return 6;
+ return SVGLength::INCH;
if (!abbr.compare("ft"))
- return 7;
+ return SVGLength::FOOT;
if (!abbr.compare("em"))
- return 8;
+ return SVGLength::EM;
if (!abbr.compare("ex"))
- return 9;
+ return SVGLength::EX;
if (!abbr.compare("%"))
- return 10;
+ return SVGLength::PERCENT;
return 0;
}
@@ -220,6 +221,36 @@ Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const
return Unit();
}
}
+Unit UnitTable::getUnit(SVGLength::Unit const u) const
+{
+ Glib::ustring u_str;
+ switch(u) {
+ case SVGLength::PX:
+ u_str = "px"; break;
+ case SVGLength::PT:
+ u_str = "pt"; break;
+ case SVGLength::PC:
+ u_str = "pc"; break;
+ case SVGLength::MM:
+ u_str = "mm"; break;
+ case SVGLength::CM:
+ u_str = "cm"; break;
+ case SVGLength::INCH:
+ u_str = "in"; break;
+ case SVGLength::FOOT:
+ u_str = "ft"; break;
+ case SVGLength::EM:
+ u_str = "em"; break;
+ case SVGLength::EX:
+ u_str = "ex"; break;
+ case SVGLength::PERCENT:
+ u_str = "%"; break;
+ default:
+ u_str = "";
+ }
+
+ return getUnit(u_str);
+}
Quantity UnitTable::getQuantity(Glib::ustring const& q) const
{
@@ -421,6 +452,27 @@ double Quantity::convert(const double from_dist, const Glib::ustring from, const
return convert(from_dist, unit_table.getUnit(from), unit_table.getUnit(to));
}
+bool operator< (const Quantity &ql, const Quantity &qr)
+{
+ if (ql.unit->type != qr.unit->type) {
+ g_warning("Incompatible units");
+ return false;
+ }
+ return ql.quantity < qr.value(*ql.unit);
+}
+bool operator> (const Quantity &ql, const Quantity &qr)
+{
+ if (ql.unit->type != qr.unit->type) {
+ g_warning("Incompatible units");
+ return false;
+ }
+ return ql.quantity > qr.value(*ql.unit);
+}
+bool operator!= (const Quantity &q1, const Quantity &q2)
+{
+ return (*q1.unit != *q2.unit) || (q1.quantity != q2.quantity);
+}
+
} // namespace Util
} // namespace Inkscape
diff --git a/src/util/units.h b/src/util/units.h
index bb202b96a..7ba6e1e86 100644
--- a/src/util/units.h
+++ b/src/util/units.h
@@ -1,5 +1,6 @@
/*
* Inkscape Units
+ * These classes are used for defining different unit systems.
*
* Authors:
* Matthew Petroff <matthew@mpetroff.net>
@@ -9,25 +10,12 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-/*
-This is a rough draft of a global 'units' thingee, to allow dialogs and
-the ruler to share info about unit systems... Dunno if this is the
-right kind of object though, so we may have to redo this or shift things
-around later when it becomes clearer what we need.
-
-This object is used for defining different unit systems.
-
-This is intended to eventually replace inkscape/helper/units.*.
-
-Need to review the Units support that's in Gtkmm already...
-
-*/
-
#ifndef INKSCAPE_UTIL_UNITS_H
#define INKSCAPE_UTIL_UNITS_H
#include <map>
#include <glibmm/ustring.h>
+#include "svg/svg-length.h"
namespace Inkscape {
namespace Util {
@@ -112,6 +100,11 @@ public:
static double convert(const double from_dist, const Glib::ustring from, const Unit &to);
static double convert(const double from_dist, const Unit &from, const Glib::ustring to);
static double convert(const double from_dist, const Glib::ustring from, const Glib::ustring to);
+
+ /** Comparison operators. */
+ friend bool operator< (const Quantity &ql, const Quantity &qr);
+ friend bool operator> (const Quantity &ql, const Quantity &qr);
+ friend bool operator!= (const Quantity &q1, const Quantity &q2);
};
class UnitTable {
@@ -132,6 +125,9 @@ class UnitTable {
/** Retrieve a given unit based on its string identifier */
Unit getUnit(Glib::ustring const &name) const;
+ /** Retrieve a given unit based on its SVGLength unit */
+ Unit getUnit(SVGLength::Unit const u) const;
+
/** Retrieve a quantity based on its string identifier */
Quantity getQuantity(Glib::ustring const &q) const;
diff --git a/src/widgets/calligraphy-toolbar.cpp b/src/widgets/calligraphy-toolbar.cpp
index 1f91b9fe2..12228ce56 100644
--- a/src/widgets/calligraphy-toolbar.cpp
+++ b/src/widgets/calligraphy-toolbar.cpp
@@ -450,7 +450,7 @@ void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-calligraphy",
1, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_ddc_width_value_changed, 1, 0 );
+ sp_ddc_width_value_changed, NULL /*unit tracker*/, 1, 0 );
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -467,7 +467,7 @@ void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
-100, 100, 1, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_ddc_velthin_value_changed, 1, 0);
+ sp_ddc_velthin_value_changed, NULL /*unit tracker*/, 1, 0);
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
}
@@ -483,7 +483,7 @@ void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
GTK_WIDGET(desktop->canvas), holder, TRUE, "calligraphy-angle",
-90.0, 90.0, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_ddc_angle_value_changed, 1, 0 );
+ sp_ddc_angle_value_changed, NULL /*unit tracker*/, 1, 0 );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
g_object_set_data( holder, "angle_action", eact );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -501,7 +501,7 @@ void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
0.0, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_ddc_flatness_value_changed, 1, 0);
+ sp_ddc_flatness_value_changed, NULL /*unit tracker*/, 1, 0);
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
}
@@ -518,7 +518,7 @@ void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
0.0, 5.0, 0.01, 0.1,
labels, values, G_N_ELEMENTS(labels),
- sp_ddc_cap_rounding_value_changed, 0.01, 2 );
+ sp_ddc_cap_rounding_value_changed, NULL /*unit tracker*/, 0.01, 2 );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
}
@@ -534,7 +534,7 @@ void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
0.0, 100, 1, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_ddc_tremor_value_changed, 1, 0);
+ sp_ddc_tremor_value_changed, NULL /*unit tracker*/, 1, 0);
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
@@ -552,7 +552,7 @@ void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
0.0, 100, 1, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_ddc_wiggle_value_changed, 1, 0);
+ sp_ddc_wiggle_value_changed, NULL /*unit tracker*/, 1, 0);
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -569,7 +569,7 @@ void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
0.0, 100, 1, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_ddc_mass_value_changed, 1, 0);
+ sp_ddc_mass_value_changed, NULL /*unit tracker*/, 1, 0);
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp
index 54344e446..2e5c2ade1 100644
--- a/src/widgets/connector-toolbar.cpp
+++ b/src/widgets/connector-toolbar.cpp
@@ -364,7 +364,7 @@ void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions,
GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-curvature",
0, 100, 1.0, 10.0,
0, 0, 0,
- connector_curvature_changed, 1, 0 );
+ connector_curvature_changed, NULL /*unit tracker*/, 1, 0 );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
// Spacing spinbox
@@ -375,7 +375,7 @@ void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions,
GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-spacing",
0, 100, 1.0, 10.0,
0, 0, 0,
- connector_spacing_changed, 1, 0 );
+ connector_spacing_changed, NULL /*unit tracker*/, 1, 0 );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
// Graph (connector network) layout
@@ -397,7 +397,7 @@ void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions,
GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-length",
10, 1000, 10.0, 100.0,
0, 0, 0,
- connector_length_changed, 1, 0 );
+ connector_length_changed, NULL /*unit tracker*/, 1, 0 );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp
index e9c2e6ef3..e9a834db7 100644
--- a/src/widgets/desktop-widget.cpp
+++ b/src/widgets/desktop-widget.cpp
@@ -2135,8 +2135,8 @@ sp_desktop_widget_update_scrollbars (SPDesktopWidget *dtw, double scale)
/* The desktop region we always show unconditionally */
SPDocument *doc = dtw->desktop->doc();
- Geom::Rect darea ( Geom::Point(-doc->getWidth(), -doc->getHeight()),
- Geom::Point(2 * doc->getWidth(), 2 * doc->getHeight()) );
+ Geom::Rect darea ( Geom::Point(-doc->getWidth().value("px"), -doc->getHeight().value("px")),
+ Geom::Point(2 * doc->getWidth().value("px"), 2 * doc->getHeight().value("px")) );
Geom::OptRect deskarea;
if (Inkscape::Preferences::get()->getInt("/tools/bounding_box") == 0) {
diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp
index 3f5e60780..1af574ed6 100644
--- a/src/widgets/eraser-toolbar.cpp
+++ b/src/widgets/eraser-toolbar.cpp
@@ -148,7 +148,7 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb
GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-eraser",
1, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_erc_width_value_changed, 1, 0);
+ sp_erc_width_value_changed, NULL /*unit tracker*/, 1, 0);
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp
index 5f29e8ed8..a68f3f451 100644
--- a/src/widgets/gradient-toolbar.cpp
+++ b/src/widgets/gradient-toolbar.cpp
@@ -1175,8 +1175,9 @@ void sp_gradient_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions,
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
0.0, 1.0, 0.01, 0.1,
0, 0, 0,
- gr_stop_offset_adjustment_changed
- , 0.01, 2, 1.0);
+ gr_stop_offset_adjustment_changed,
+ NULL /*unit tracker*/,
+ 0.01, 2, 1.0);
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
g_object_set_data( holder, "offset_action", eact );
diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp
index dda453bc4..feb69cc64 100644
--- a/src/widgets/icon.cpp
+++ b/src/widgets/icon.cpp
@@ -42,6 +42,7 @@
#include "display/drawing.h"
#include "io/sys.h"
#include "sp-root.h"
+#include "util/units.h"
#include "icon.h"
@@ -1137,7 +1138,7 @@ sp_icon_doc_icon( SPDocument *doc, Inkscape::Drawing &drawing,
if ( object->parent == NULL )
{
dbox = Geom::Rect(Geom::Point(0, 0),
- Geom::Point(doc->getWidth(), doc->getHeight()));
+ Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px")));
}
/* This is in document coordinates, i.e. pixels */
diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp
index 37763ab34..582243870 100644
--- a/src/widgets/mesh-toolbar.cpp
+++ b/src/widgets/mesh-toolbar.cpp
@@ -265,7 +265,7 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
1, 20, 1, 1,
labels, values, G_N_ELEMENTS(labels),
- ms_row_changed,
+ ms_row_changed, NULL /*unit tracker*/,
1.0, 0 );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -281,7 +281,7 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
1, 20, 1, 1,
labels, values, G_N_ELEMENTS(labels),
- ms_col_changed,
+ ms_col_changed, NULL /*unit tracker*/,
1.0, 0 );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp
index a9e298f1d..c3e5b22ce 100644
--- a/src/widgets/node-toolbar.cpp
+++ b/src/widgets/node-toolbar.cpp
@@ -595,7 +595,7 @@ void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-nodes",
-1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
labels, values, G_N_ELEMENTS(labels),
- sp_node_path_x_value_changed );
+ sp_node_path_x_value_changed, tracker );
tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
g_object_set_data( holder, "nodes_x_action", eact );
gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
@@ -613,7 +613,7 @@ void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
-1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
labels, values, G_N_ELEMENTS(labels),
- sp_node_path_y_value_changed );
+ sp_node_path_y_value_changed, tracker );
tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
g_object_set_data( holder, "nodes_y_action", eact );
gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
diff --git a/src/widgets/paintbucket-toolbar.cpp b/src/widgets/paintbucket-toolbar.cpp
index 1d8ae7ae9..028753b59 100644
--- a/src/widgets/paintbucket-toolbar.cpp
+++ b/src/widgets/paintbucket-toolbar.cpp
@@ -169,7 +169,7 @@ void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
"/tools/paintbucket/threshold", 5, GTK_WIDGET(desktop->canvas), holder, TRUE,
"inkscape:paintbucket-threshold", 0, 100.0, 1.0, 10.0,
0, 0, 0,
- paintbucket_threshold_changed, 1, 0 );
+ paintbucket_threshold_changed, NULL /*unit tracker*/, 1, 0 );
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
@@ -197,7 +197,7 @@ void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
"/tools/paintbucket/offset", 0, GTK_WIDGET(desktop->canvas), holder, TRUE,
"inkscape:paintbucket-offset", -1e4, 1e4, 0.1, 0.5,
0, 0, 0,
- paintbucket_offset_changed, 1, 2);
+ paintbucket_offset_changed, tracker, 1, 2);
tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp
index 851ad7134..f112a35fa 100644
--- a/src/widgets/pencil-toolbar.cpp
+++ b/src/widgets/pencil-toolbar.cpp
@@ -307,6 +307,7 @@ void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb
1, 100.0, 0.5, 1.0,
labels, values, G_N_ELEMENTS(labels),
sp_pencil_tb_tolerance_value_changed,
+ NULL /*unit tracker*/,
1, 2);
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp
index fb64ae14b..0d5d3a688 100644
--- a/src/widgets/rect-toolbar.cpp
+++ b/src/widgets/rect-toolbar.cpp
@@ -114,7 +114,7 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *
for (GSList const *items = selection->itemList(); items != NULL; items = items->next) {
if (SP_IS_RECT(items->data)) {
if (gtk_adjustment_get_value(adj) != 0) {
- (SP_RECT(items->data)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"));
+ (SP_RECT(items->data)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, *sp_desktop_namedview(desktop)->doc_units));
} else {
SP_OBJECT(items->data)->getRepr()->setAttribute(value_name, NULL);
}
@@ -186,6 +186,7 @@ static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar con
UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) );
Unit const unit = tracker->getActiveUnit();
+ Unit const doc_unit = *sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units;
gpointer item = g_object_get_data( tbl, "item" );
if (item && SP_IS_RECT(item)) {
@@ -193,28 +194,28 @@ static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar con
GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "rx" ) );
gdouble rx = SP_RECT(item)->getVisibleRx();
- gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit));
+ gtk_adjustment_set_value(adj, Quantity::convert(rx, doc_unit, unit));
}
{
GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "ry" ) );
gdouble ry = SP_RECT(item)->getVisibleRy();
- gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit));
+ gtk_adjustment_set_value(adj, Quantity::convert(ry, doc_unit, unit));
}
{
GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) );
gdouble width = SP_RECT(item)->getVisibleWidth();
- gtk_adjustment_set_value(adj, Quantity::convert(width, "px", unit));
+ gtk_adjustment_set_value(adj, Quantity::convert(width, doc_unit, unit));
}
{
GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) );
gdouble height = SP_RECT(item)->getVisibleHeight();
- gtk_adjustment_set_value(adj, Quantity::convert(height, "px", unit));
+ gtk_adjustment_set_value(adj, Quantity::convert(height, doc_unit, unit));
}
}
@@ -322,7 +323,7 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-rect",
0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
labels, values, G_N_ELEMENTS(labels),
- sp_rtb_width_value_changed );
+ sp_rtb_width_value_changed, tracker);
tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
g_object_set_data( holder, "width_action", eact );
gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
@@ -339,7 +340,7 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
labels, values, G_N_ELEMENTS(labels),
- sp_rtb_height_value_changed );
+ sp_rtb_height_value_changed, tracker);
tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
g_object_set_data( holder, "height_action", eact );
gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
@@ -356,7 +357,7 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
labels, values, G_N_ELEMENTS(labels),
- sp_rtb_rx_value_changed);
+ sp_rtb_rx_value_changed, tracker);
tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
}
@@ -371,7 +372,7 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
labels, values, G_N_ELEMENTS(labels),
- sp_rtb_ry_value_changed);
+ sp_rtb_ry_value_changed, tracker);
tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
}
diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp
index e4a5a2905..590b0867f 100644
--- a/src/widgets/select-toolbar.cpp
+++ b/src/widgets/select-toolbar.cpp
@@ -273,7 +273,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw)
g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
}
-static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits )
+static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker )
{
#if WITH_GTKMM_3_0
Glib::RefPtr<Gtk::Adjustment> adj = Glib::wrap(adjustment, true);
@@ -281,6 +281,7 @@ static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRa
#else
Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(*Glib::wrap(adjustment, true), climbRate, digits);
#endif
+ inkSpinner->addUnitTracker(unit_tracker);
inkSpinner = Gtk::manage( inkSpinner );
GtkWidget *widget = GTK_WIDGET( inkSpinner->gobj() );
return widget;
@@ -313,7 +314,7 @@ static EgeAdjustmentAction * create_adjustment_action( gchar const *name,
g_object_set_data( G_OBJECT(spw), data, adj );
}
- EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, Q_(label), tooltip, 0, SPIN_STEP, 3 );
+ EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, Q_(label), tooltip, 0, SPIN_STEP, 3, tracker );
if ( shortLabel ) {
g_object_set( act, "short_label", Q_(shortLabel), NULL );
}
diff --git a/src/widgets/spiral-toolbar.cpp b/src/widgets/spiral-toolbar.cpp
index cccaf5154..b4e8e68a7 100644
--- a/src/widgets/spiral-toolbar.cpp
+++ b/src/widgets/spiral-toolbar.cpp
@@ -262,7 +262,7 @@ void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb
GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-spiral",
0.01, 1024.0, 0.1, 1.0,
labels, values, G_N_ELEMENTS(labels),
- sp_spl_tb_revolution_value_changed, 1, 2);
+ sp_spl_tb_revolution_value_changed, NULL /*unit tracker*/, 1, 2);
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
}
diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp
index fe221f695..247df53e2 100644
--- a/src/widgets/spray-toolbar.cpp
+++ b/src/widgets/spray-toolbar.cpp
@@ -130,7 +130,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-spray",
1, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_spray_width_value_changed, 1, 0 );
+ sp_spray_width_value_changed, NULL /*unit tracker*/, 1, 0 );
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -146,7 +146,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-mean",
0, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_spray_mean_value_changed, 1, 0 );
+ sp_spray_mean_value_changed, NULL /*unit tracker*/, 1, 0 );
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -162,7 +162,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-standard_deviation",
1, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_spray_standard_deviation_value_changed, 1, 0 );
+ sp_spray_standard_deviation_value_changed, NULL /*unit tracker*/, 1, 0 );
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -223,7 +223,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-population",
1, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_spray_population_value_changed, 1, 0 );
+ sp_spray_population_value_changed, NULL /*unit tracker*/, 1, 0 );
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -254,7 +254,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-rotation",
0, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_spray_rotation_value_changed, 1, 0 );
+ sp_spray_rotation_value_changed, NULL /*unit tracker*/, 1, 0 );
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -272,7 +272,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-scale",
0, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_spray_scale_value_changed, 1, 0 );
+ sp_spray_scale_value_changed, NULL /*unit tracker*/, 1, 0 );
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp
index 9f7dd95e0..9e26988ff 100644
--- a/src/widgets/star-toolbar.cpp
+++ b/src/widgets/star-toolbar.cpp
@@ -504,7 +504,7 @@ void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
3, 1024, 1, 5,
labels, values, G_N_ELEMENTS(labels),
- sp_stb_magnitude_value_changed,
+ sp_stb_magnitude_value_changed, NULL /*unit tracker*/,
1.0, 0 );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -559,7 +559,7 @@ void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
-10.0, 10.0, 0.001, 0.01,
labels, values, G_N_ELEMENTS(labels),
- sp_stb_randomized_value_changed, 0.1, 3 );
+ sp_stb_randomized_value_changed, NULL /*unit tracker*/, 0.1, 3 );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
}
diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp
index 7554f4faf..6b9fc900c 100644
--- a/src/widgets/text-toolbar.cpp
+++ b/src/widgets/text-toolbar.cpp
@@ -1459,6 +1459,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
0.0, 10.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */
labels, values, G_N_ELEMENTS(labels), /* drop down menu */
sp_text_lineheight_value_changed, /* callback */
+ NULL, /* unit tracker */
0.1, /* step (used?) */
2, /* digits to show */
1.0 /* factor (multiplies default) */
@@ -1489,6 +1490,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
-100.0, 100.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */
labels, values, G_N_ELEMENTS(labels), /* drop down menu */
sp_text_wordspacing_value_changed, /* callback */
+ NULL, /* unit tracker */
0.1, /* step (used?) */
2, /* digits to show */
1.0 /* factor (multiplies default) */
@@ -1519,6 +1521,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
-100.0, 100.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */
labels, values, G_N_ELEMENTS(labels), /* drop down menu */
sp_text_letterspacing_value_changed, /* callback */
+ NULL, /* unit tracker */
0.1, /* step (used?) */
2, /* digits to show */
1.0 /* factor (multiplies default) */
@@ -1549,6 +1552,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
-100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */
labels, values, G_N_ELEMENTS(labels), /* drop down menu */
sp_text_dx_value_changed, /* callback */
+ NULL, /* unit tracker */
0.1, /* step (used?) */
2, /* digits to show */
1.0 /* factor (multiplies default) */
@@ -1579,6 +1583,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
-100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */
labels, values, G_N_ELEMENTS(labels), /* drop down menu */
sp_text_dy_value_changed, /* callback */
+ NULL, /* unit tracker */
0.1, /* step (used?) */
2, /* digits to show */
1.0 /* factor (multiplies default) */
@@ -1609,6 +1614,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
-180.0, 180.0, 0.1, 1.0, /* lower, upper, step (arrow up/down), page up/down */
labels, values, G_N_ELEMENTS(labels), /* drop down menu */
sp_text_rotation_value_changed, /* callback */
+ NULL, /* unit tracker */
0.1, /* step (used?) */
2, /* digits to show */
1.0 /* factor (multiplies default) */
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index 6d650df49..ddbe77fbb 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -1012,7 +1012,7 @@ GtkWidget *ToolboxFactory::createSnapToolbox()
return toolboxNewCommon( tb, BAR_SNAP, GTK_POS_LEFT );
}
-static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits )
+static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker)
{
#if WITH_GTKMM_3_0
Glib::RefPtr<Gtk::Adjustment> adj = Glib::wrap(adjustment, true);
@@ -1020,6 +1020,7 @@ static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRa
#else
Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(*Glib::wrap(adjustment, true), climbRate, digits);
#endif
+ inkSpinner->addUnitTracker(unit_tracker);
inkSpinner = Gtk::manage( inkSpinner );
GtkWidget *widget = GTK_WIDGET( inkSpinner->gobj() );
return widget;
@@ -1034,6 +1035,7 @@ EgeAdjustmentAction * create_adjustment_action( gchar const *name,
gdouble lower, gdouble upper, gdouble step, gdouble page,
gchar const** descrLabels, gdouble const* descrValues, guint descrCount,
void (*callback)(GtkAdjustment *, GObject *),
+ Inkscape::UI::Widget::UnitTracker *unit_tracker,
gdouble climb/* = 0.1*/, guint digits/* = 3*/, double factor/* = 1.0*/ )
{
static bool init = false;
@@ -1048,7 +1050,7 @@ EgeAdjustmentAction * create_adjustment_action( gchar const *name,
g_signal_connect( G_OBJECT(adj), "value-changed", G_CALLBACK(callback), dataKludge );
- EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, label, tooltip, 0, climb, digits );
+ EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, label, tooltip, 0, climb, digits, unit_tracker );
if ( shortLabel ) {
g_object_set( act, "short_label", shortLabel, NULL );
}
diff --git a/src/widgets/toolbox.h b/src/widgets/toolbox.h
index 0ae4d4630..e9ffcda4a 100644
--- a/src/widgets/toolbox.h
+++ b/src/widgets/toolbox.h
@@ -28,6 +28,10 @@ class SPEventContext;
namespace Inkscape {
namespace UI {
+namespace Widget {
+ class UnitTracker;
+}
+
/**
* Main toolbox source.
*/
@@ -123,6 +127,7 @@ void delete_connection(GObject * /*obj*/, sigc::connection *connection);
gdouble lower, gdouble upper, gdouble step, gdouble page,
gchar const** descrLabels, gdouble const* descrValues, guint descrCount,
void (*callback)(GtkAdjustment *, GObject *),
+ Inkscape::UI::Widget::UnitTracker *unit_tracker = NULL,
gdouble climb = 0.1, guint digits = 3, double factor = 1.0 );
#endif /* !SEEN_TOOLBOX_H */
diff --git a/src/widgets/tweak-toolbar.cpp b/src/widgets/tweak-toolbar.cpp
index d5fe67ef7..6da7608bd 100644
--- a/src/widgets/tweak-toolbar.cpp
+++ b/src/widgets/tweak-toolbar.cpp
@@ -144,7 +144,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-tweak",
1, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_tweak_width_value_changed, 0.01, 0, 100 );
+ sp_tweak_width_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 );
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -161,7 +161,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, TRUE, "tweak-force",
1, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_tweak_force_value_changed, 0.01, 0, 100 );
+ sp_tweak_force_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 );
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
@@ -370,7 +370,7 @@ void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj
GTK_WIDGET(desktop->canvas), holder, TRUE, "tweak-fidelity",
1, 100, 1.0, 10.0,
labels, values, G_N_ELEMENTS(labels),
- sp_tweak_fidelity_value_changed, 0.01, 0, 100 );
+ sp_tweak_fidelity_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
if (mode == TWEAK_MODE_COLORPAINT || mode == TWEAK_MODE_COLORJITTER) {