diff options
| author | Markus Engel <markus.engel@tum.de> | 2013-09-24 22:17:24 +0000 |
|---|---|---|
| committer | Markus Engel <markus.engel@tum.de> | 2013-09-24 22:17:24 +0000 |
| commit | bcca22a25ae98f70c36fff6292f0a8fe4e578d89 (patch) | |
| tree | a18d382d32f471b7119b9b7b2782cec04d6da43f /src | |
| parent | Refactored SPUse. (diff) | |
| parent | Fix my email address through codebase (diff) | |
| download | inkscape-bcca22a25ae98f70c36fff6292f0a8fe4e578d89.tar.gz inkscape-bcca22a25ae98f70c36fff6292f0a8fe4e578d89.zip | |
Merged from trunk (r12588).
(bzr r11608.1.129)
Diffstat (limited to 'src')
182 files changed, 2649 insertions, 7200 deletions
diff --git a/src/2geom/conjugate_gradient.cpp b/src/2geom/conjugate_gradient.cpp index ae69d5281..588513414 100644 --- a/src/2geom/conjugate_gradient.cpp +++ b/src/2geom/conjugate_gradient.cpp @@ -36,6 +36,9 @@ /* lifted wholely from wikipedia. */ +namespace Geom +{ + using std::valarray; static void @@ -126,6 +129,8 @@ conjugate_gradient(valarray<double> const &A, // x is solution } +} // namespace Geom + /* Local Variables: mode:c++ diff --git a/src/2geom/conjugate_gradient.h b/src/2geom/conjugate_gradient.h index a34307d4b..4f500c0e6 100644 --- a/src/2geom/conjugate_gradient.h +++ b/src/2geom/conjugate_gradient.h @@ -29,11 +29,14 @@ * */ -#ifndef _CONJUGATE_GRADIENT_H -#define _CONJUGATE_GRADIENT_H +#ifndef _2GEOM_CONJUGATE_GRADIENT_H +#define _2GEOM_CONJUGATE_GRADIENT_H #include <valarray> +namespace Geom +{ + double inner(std::valarray<double> const &x, std::valarray<double> const &y); @@ -44,7 +47,10 @@ conjugate_gradient(std::valarray<double> const &A, std::valarray<double> const &b, unsigned n, double tol, unsigned max_iterations, bool ortho1); -#endif // _CONJUGATE_GRADIENT_H + +} // namespace Geom + +#endif // _2GEOM_CONJUGATE_GRADIENT_H /* Local Variables: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a09bceb06..32bcf19a7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,16 +40,17 @@ set(sp_SRC sp-item-update-cns.cpp sp-item.cpp sp-line.cpp + sp-linear-gradient.cpp sp-lpe-item.cpp sp-mask.cpp sp-mesh-array.cpp + sp-mesh-gradient.cpp sp-mesh-patch.cpp sp-mesh-row.cpp sp-metadata.cpp sp-missing-glyph.cpp sp-namedview.cpp sp-object-group.cpp - sp-object-repr.cpp sp-object.cpp sp-offset.cpp sp-paint-server.cpp @@ -57,6 +58,7 @@ set(sp_SRC sp-pattern.cpp sp-polygon.cpp sp-polyline.cpp + sp-radial-gradient.cpp sp-rect.cpp sp-root.cpp sp-script.cpp @@ -92,6 +94,7 @@ set(sp_SRC sp-defs.h sp-desc.h sp-ellipse.h + sp-factory.h sp-filter-primitive.h sp-filter-reference.h sp-filter-units.h @@ -103,7 +106,6 @@ set(sp_SRC sp-font.h sp-glyph-kerning.h sp-glyph.h - sp-gradient-fns.h sp-gradient-reference.h sp-gradient-spread.h sp-gradient-test.h @@ -121,23 +123,18 @@ set(sp_SRC sp-item-update-cns.h sp-item.h sp-line.h - sp-linear-gradient-fns.h sp-linear-gradient.h sp-lpe-item.h sp-marker-loc.h sp-mask.h sp-mesh-array.h - sp-mesh-gradient-fns.h sp-mesh-gradient.h - sp-mesh-patch-fns.h sp-mesh-patch.h - sp-mesh-row-fns.h sp-mesh-row.h sp-metadata.h sp-missing-glyph.h sp-namedview.h sp-object-group.h - sp-object-repr.h sp-object.h sp-offset.h sp-paint-server-reference.h @@ -146,7 +143,6 @@ set(sp_SRC sp-pattern.h sp-polygon.h sp-polyline.h - sp-radial-gradient-fns.h sp-radial-gradient.h sp-rect.h sp-root.h @@ -357,6 +353,7 @@ set(inkscape_SRC event.h extract-uri-test.h extract-uri.h + factory.h file.h fill-or-stroke.h filter-chemistry.h @@ -393,7 +390,7 @@ set(inkscape_SRC knotholder.h layer-fns.h layer-manager.h - layer-model.h + layer-model.h line-geometry.h line-snapper.h lpe-tool-context.h @@ -474,6 +471,7 @@ set(inkscape_SRC text-context.h text-editing.h text-tag-attributes.h + tool-factory.h tools-switch.h transf_mat_3x4.h tweak-context.h @@ -490,7 +488,7 @@ set(inkscape_SRC ) if(WIN32) - list(APPEND inkscape_SRC + list(APPEND inkscape_SRC registrytool.cpp #deptool.cpp winmain.cpp @@ -571,21 +569,21 @@ set(inkscape_SRC # ----------------------------------------------------------------------------- # Setup the executable # ----------------------------------------------------------------------------- -add_inkscape_lib(sp_LIB "${sp_SRC}") -add_inkscape_lib(inkscape_LIB "${inkscape_SRC}") +#add_inkscape_lib(sp_LIB "${sp_SRC}") +#add_inkscape_lib(inkscape_LIB "${inkscape_SRC}") # make executable for INKSCAPE -add_executable(inkscape ${main_SRC}) +add_executable(inkscape ${main_SRC} ${inkscape_SRC} ${sp_SRC}) add_dependencies(inkscape inkscape_version) target_link_libraries(inkscape # order from automake - sp_LIB + #sp_LIB nrtype_LIB - inkscape_LIB - sp_LIB # annoying, we need both! + #inkscape_LIB + #sp_LIB # annoying, we need both! nrtype_LIB # annoying, we need both! dom_LIB @@ -597,6 +595,7 @@ target_link_libraries(inkscape livarot_LIB uemf_LIB 2geom_LIB + depixelize_LIB ${INKSCAPE_LIBS} ) diff --git a/src/Makefile.am b/src/Makefile.am index a0c240252..a45a33932 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -267,7 +267,7 @@ TESTS = $(check_PROGRAMS) ../share/extensions/test/run-all-extension-tests XFAIL_TESTS = $(check_PROGRAMS) # including the the testsuites here ensures that they get distributed -cxxtests_SOURCES = cxxtests.cpp $(CXXTEST_TESTSUITES) +cxxtests_SOURCES = cxxtests.cpp $(CXXTEST_TESTSUITES) $(ink_common_sources) $(win32_sources) cxxtests_LDADD = $(all_libs) cxxtests.cpp: $(CXXTEST_TESTSUITES) $(CXXTEST_TEMPLATE) 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/box3d-context.cpp b/src/box3d-context.cpp index 912c67801..f270fa244 100644 --- a/src/box3d-context.cpp +++ b/src/box3d-context.cpp @@ -585,7 +585,7 @@ void Box3DContext::drag(guint state) { box3d_position_set(this->box3d); // status text - this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("<b>3D Box</b>; with <b>Shift</b> to extrude along the Z axis")); + this->message_context->setF(Inkscape::NORMAL_MESSAGE, "%s", _("<b>3D Box</b>; with <b>Shift</b> to extrude along the Z axis")); } void Box3DContext::finishItem() { diff --git a/src/box3d.cpp b/src/box3d.cpp index 0f528a592..193051ee5 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -255,11 +255,8 @@ Inkscape::XML::Node* SPBox3D::write(Inkscape::XML::Document *xml_doc, Inkscape:: return repr; } -gchar* SPBox3D::description() { - SPBox3D* item = this; - - g_return_val_if_fail(SP_IS_BOX3D(item), NULL); - return g_strdup(_("<b>3D Box</b>")); +const char* SPBox3D::display_name() { + return _("3D Box"); } void box3d_position_set(SPBox3D *box) diff --git a/src/box3d.h b/src/box3d.h index 18d99d60a..be5f1926c 100644 --- a/src/box3d.h +++ b/src/box3d.h @@ -58,7 +58,7 @@ public: virtual void update(SPCtx *ctx, guint flags); virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual gchar *description(); + virtual const char* display_name(); virtual Geom::Affine set_transform(Geom::Affine const &transform); virtual void convert_to_guides(); }; diff --git a/src/color-profile-test.h b/src/color-profile-test.h index b3ead5d55..4276eb774 100644 --- a/src/color-profile-test.h +++ b/src/color-profile-test.h @@ -31,13 +31,13 @@ public: static void createSuiteSubclass( ColorProfileTest*& dst ) { - Inkscape::ColorProfile *prof = static_cast<Inkscape::ColorProfile *>(g_object_new(COLORPROFILE_TYPE, NULL)); + Inkscape::ColorProfile *prof = new Inkscape::ColorProfile(); if ( prof ) { if ( prof->rendering_intent == (guint)Inkscape::RENDERING_INTENT_UNKNOWN ) { TS_ASSERT_EQUALS( prof->rendering_intent, (guint)Inkscape::RENDERING_INTENT_UNKNOWN ); dst = new ColorProfileTest(); } - g_object_unref(prof); + delete prof; } } @@ -74,7 +74,7 @@ public: {"auto2", (guint)Inkscape::RENDERING_INTENT_UNKNOWN}, }; - Inkscape::ColorProfile *prof = static_cast<Inkscape::ColorProfile *>(g_object_new(COLORPROFILE_TYPE, NULL)); + Inkscape::ColorProfile *prof = new Inkscape::ColorProfile(); TS_ASSERT( prof ); SP_OBJECT(prof)->document = _doc; @@ -84,7 +84,7 @@ public: TSM_ASSERT_EQUALS( descr, prof->rendering_intent, (guint)cases[i].intVal ); } - g_object_unref(prof); + delete prof; } void testSetLocal() @@ -94,7 +94,7 @@ public: "something", }; - Inkscape::ColorProfile *prof = static_cast<Inkscape::ColorProfile *>(g_object_new(COLORPROFILE_TYPE, NULL)); + Inkscape::ColorProfile *prof = new Inkscape::ColorProfile(); TS_ASSERT( prof ); SP_OBJECT(prof)->document = _doc; @@ -108,7 +108,7 @@ public: SP_OBJECT(prof)->setKeyValue( SP_ATTR_LOCAL, NULL); TS_ASSERT_EQUALS( prof->local, (gchar*)0 ); - g_object_unref(prof); + delete prof; } void testSetName() @@ -118,7 +118,7 @@ public: "something", }; - Inkscape::ColorProfile *prof = static_cast<Inkscape::ColorProfile *>(g_object_new(COLORPROFILE_TYPE, NULL)); + Inkscape::ColorProfile *prof = new Inkscape::ColorProfile(); TS_ASSERT( prof ); SP_OBJECT(prof)->document = _doc; @@ -132,7 +132,7 @@ public: SP_OBJECT(prof)->setKeyValue( SP_ATTR_NAME, NULL); TS_ASSERT_EQUALS( prof->name, (gchar*)0 ); - g_object_unref(prof); + delete prof; } }; 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/display/drawing-item.cpp b/src/display/drawing-item.cpp index a9836a9e3..1af07cb44 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -281,8 +281,15 @@ DrawingItem::setZOrder(unsigned z) _markForRendering(); } -void -DrawingItem::setItemBounds(Geom::OptRect const &bounds) +void DrawingItem::setItemBounds(Geom::OptRect const &bounds) +{ + if (!bounds) return; + Geom::IntRect copy = bounds->roundOutwards(); + if (_filter) _filter->area_enlarge(copy, this); + this->setFilterBounds(copy); +} + +void DrawingItem::setFilterBounds(Geom::OptRect const &bounds) { if (bounds) _filter_bbox = bounds; } @@ -352,10 +359,10 @@ DrawingItem::update(Geom::IntRect const &area, UpdateContext const &ctx, unsigne if (to_update & STATE_BBOX) { // compute drawbox - if (_filter && render_filters && _bbox) { - Geom::IntRect newbox(*_bbox); - _filter->area_enlarge(newbox, this); - _drawbox = Geom::OptIntRect(newbox); + if (_filter && render_filters && _filter_bbox) { + Geom::OptRect enlarged = _filter_bbox; + *enlarged *= ctm(); + _drawbox = enlarged->roundOutwards(); } else { _drawbox = _bbox; } diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index 8020659db..c69b996b4 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -113,6 +113,7 @@ public: void setMask(DrawingItem *item); void setZOrder(unsigned z); void setItemBounds(Geom::OptRect const &bounds); + void setFilterBounds(Geom::OptRect const &bounds); void setKey(unsigned key) { _key = key; } unsigned key() const { return _key; } diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index a0103cbb0..c0044c5d8 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -117,9 +117,7 @@ int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, D // Get filter are, the filter_effect_area is already done in visualBounds Geom::OptRect filter_area = item->filterBounds(); // Use the geometricBounds as a backup solution - if (!filter_area || (filter_area->hasZeroArea() && - filter_area->min()[Geom::X] == 0 && filter_area->min()[Geom::Y] == 0)) - filter_area = item->geometricBounds(); + if (!filter_area) return 1; FilterUnits units(_filter_units, _primitive_units); units.set_ctm(trans); diff --git a/src/document.cpp b/src/document.cpp index ec831745c..800f2f33d 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -548,81 +548,90 @@ 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(); + u = SVGLength::PX; } - 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) { - if (root->width.unit == SVGLength::PERCENT && root->viewBox_set) { // set to viewBox= - root->viewBox.setMax(Geom::Point(root->viewBox.left() + width.value("px"), root->viewBox.bottom())); - } else { // set to width= - gdouble old_computed = root->width.computed; - root->width.computed = width.value("px"); - /* SVG does not support meters as a unit, so we must translate meters to - * cm when writing */ - if (*width.unit == unit_table.getUnit("m")) { - root->width.value = width.value("cm"); - root->width.unit = SVGLength::CM; - } else { - root->width.value = width.quantity; - root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); - } - - if (root->viewBox_set) - root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.computed / old_computed) * root->viewBox.width(), root->viewBox.bottom())); + gdouble old_computed = root->width.computed; + root->width.computed = width.value("px"); + /* SVG does not support meters as a unit, so we must translate meters to + * cm when writing */ + if (*width.unit == unit_table.getUnit("m")) { + root->width.value = width.value("cm"); + root->width.unit = SVGLength::CM; + } else { + root->width.value = width.quantity; + root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); } + if (root->viewBox_set) + root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.computed / old_computed) * root->viewBox.width(), root->viewBox.bottom())); + 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(); + u = SVGLength::PX; } - 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) { - if (root->height.unit == SVGLength::PERCENT && root->viewBox_set) { // set to viewBox= - root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + height.value("px"))); - } else { // set to height= - gdouble old_computed = root->height.computed; - root->height.computed = height.value("px"); - /* SVG does not support meters as a unit, so we must translate meters to - * cm when writing */ - if (*height.unit == unit_table.getUnit("m")) { - root->height.value = height.value("cm"); - root->height.unit = SVGLength::CM; - } else { - root->height.value = height.quantity; - root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); - } - - if (root->viewBox_set) - root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.computed / old_computed) * root->viewBox.height())); + gdouble old_computed = root->height.computed; + root->height.computed = height.value("px"); + /* SVG does not support meters as a unit, so we must translate meters to + * cm when writing */ + if (*height.unit == unit_table.getUnit("m")) { + root->height.value = height.value("cm"); + root->height.unit = SVGLength::CM; + } else { + root->height.value = height.quantity; + root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); } + if (root->viewBox_set) + root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.computed / old_computed) * root->viewBox.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 +653,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 +988,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/dom/CMakeLists.txt b/src/dom/CMakeLists.txt index 7c49466c2..c3078a8e3 100644 --- a/src/dom/CMakeLists.txt +++ b/src/dom/CMakeLists.txt @@ -38,7 +38,6 @@ set(dom_SRC smilimpl.h stylesheets.h svg.h - svg2.h svgimpl.h svgreader.h svgtypes.h diff --git a/src/dom/Makefile_insert b/src/dom/Makefile_insert index 25629efb2..6d222987e 100644 --- a/src/dom/Makefile_insert +++ b/src/dom/Makefile_insert @@ -27,7 +27,6 @@ dom_libdom_a_SOURCES = \ dom/smilimpl.cpp \ dom/smilimpl.h \ dom/stylesheets.h \ - dom/svg2.h \ dom/svg.h \ dom/svgimpl.cpp \ dom/svgimpl.h \ diff --git a/src/dom/svg2.h b/src/dom/svg2.h deleted file mode 100644 index 011bafbea..000000000 --- a/src/dom/svg2.h +++ /dev/null @@ -1,5560 +0,0 @@ -#ifndef SEEN_SVG_H -#define SEEN_SVG_H - -/** - * @file - * Phoebe DOM Implementation. - * - * This is a C++ approximation of the W3C DOM model, which follows - * fairly closely the specifications in the various .idl files, copies of - * which are provided for reference. Most important is this one: - * - * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html - */ -/* - * Authors: - * Bob Jamison - * - * Copyright(C) 2005-2008 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or(at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * ======================================================================= - * NOTES - * - * This API follows: - * http://www.w3.org/TR/SVG11/svgdom.html - * - * This file defines the main SVG-DOM Node types. Other non-Node types are - * defined in svgtypes.h. - * - */ - - -// For access to DOM2 core -#include "dom/dom.h" - -// For access to DOM2 events -#include "dom/events.h" - -// For access to those parts from DOM2 CSS OM used by SVG DOM. -#include "dom/css.h" - -// For access to those parts from DOM2 Views OM used by SVG DOM. -#include "dom/views.h" - -// For access to the SMIL OM used by SVG DOM. -#include "dom/smil.h" - - -#include <math.h> - -#define SVG_NAMESPACE "http://www.w3.org/2000/svg" - - -namespace org -{ -namespace w3c -{ -namespace dom -{ -namespace svg -{ - - -//local definitions -typedef dom::DOMString DOMString; -typedef dom::DOMException DOMException; -typedef dom::Element Element; -typedef dom::ElementPtr ElementPtr; -typedef dom::Document Document; -typedef dom::DocumentPtr DocumentPtr; -typedef dom::NodeList NodeList; - - - - -class SVGElement; -typedef Ptr<SVGElement> SVGElementPtr; -class SVGUseElement; -typedef Ptr<SVGUseElement> SVGUseElementPtr; -class SVGDocument; -typedef Ptr<SVGDocument> SVGDocumentPtr; - -/*######################################################################### -## SVGException -#########################################################################*/ - -/** - * - */ -class SVGException -{ -public: - - /** - * SVGExceptionCode - */ - typedef enum - { - SVG_WRONG_TYPE_ERR = 0, - SVG_INVALID_VALUE_ERR = 1, - SVG_MATRIX_NOT_INVERTABLE = 2 - } SVGExceptionCode; - - unsigned short code; -}; - - - - - - - -//######################################################################## -//######################################################################## -//# V A L U E S -//######################################################################## -//######################################################################## - - - - - -/*######################################################################### -## SVGAngle -#########################################################################*/ - -/** - * - */ -class SVGAngle -{ -public: - - /** - * Angle Unit Types - */ - typedef enum - { - SVG_ANGLETYPE_UNKNOWN = 0, - SVG_ANGLETYPE_UNSPECIFIED = 1, - SVG_ANGLETYPE_DEG = 2, - SVG_ANGLETYPE_RAD = 3, - SVG_ANGLETYPE_GRAD = 4 - } AngleUnitType; - - /** - * - */ - unsigned short getUnitType(); - - /** - * - */ - double getValue(); - - /** - * - */ - void setValue(double val) throw(DOMException); - - /** - * - */ - double getValueInSpecifiedUnits(); - - /** - * - */ - void setValueInSpecifiedUnits(double /*val*/) - throw(DOMException); - - /** - * - */ - DOMString getValueAsString(); - - /** - * - */ - void setValueAsString(const DOMString &/*val*/) - throw(DOMException); - - /** - * - */ - void newValueSpecifiedUnits(unsigned short /*unitType*/, - double /*valueInSpecifiedUnits*/); - - /** - * - */ - void convertToSpecifiedUnits(unsigned short /*unitType*/); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGAngle(); - - /** - * - */ - SVGAngle(const SVGAngle &other); - - /** - * - */ - ~SVGAngle(); - -protected: - - int unitType; - - double value; - -}; - - -/*######################################################################### -## SVGLength -#########################################################################*/ - -/** - * - */ -class SVGLength -{ -public: - - /** - * Length Unit Types - */ - typedef enum - { - SVG_LENGTHTYPE_UNKNOWN = 0, - SVG_LENGTHTYPE_NUMBER = 1, - SVG_LENGTHTYPE_PERCENTAGE = 2, - SVG_LENGTHTYPE_EMS = 3, - SVG_LENGTHTYPE_EXS = 4, - SVG_LENGTHTYPE_PX = 5, - SVG_LENGTHTYPE_CM = 6, - SVG_LENGTHTYPE_MM = 7, - SVG_LENGTHTYPE_IN = 8, - SVG_LENGTHTYPE_PT = 9, - SVG_LENGTHTYPE_PC = 10 - } LengthUnitType; - - /** - * - */ - unsigned short getUnitType(); - - /** - * - */ - double getValue(); - - /** - * - */ - void setValue(double val) throw(DOMException); - - /** - * - */ - double getValueInSpecifiedUnits(); - - /** - * - */ - void setValueInSpecifiedUnits(double /*val*/) throw(DOMException); - - /** - * - */ - DOMString getValueAsString(); - - /** - * - */ - void setValueAsString(const DOMString& /*val*/) throw(DOMException); - - /** - * - */ - void newValueSpecifiedUnits(unsigned short /*unitType*/, double /*val*/); - - /** - * - */ - void convertToSpecifiedUnits(unsigned short /*unitType*/); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGLength(); - - /** - * - */ - SVGLength(const SVGLength &other); - - /** - * - */ - ~SVGLength(); - -protected: - - int unitType; - - double value; - -}; - -/*######################################################################### -## SVGMatrix -#########################################################################*/ - -/** - * In SVG, a Matrix is defined like this: - * - * | a c e | - * | b d f | - * | 0 0 1 | - * - */ -class SVGMatrix -{ -public: - - - /** - * - */ - double getA(); - - /** - * - */ - void setA(double val) throw(DOMException); - - /** - * - */ - double getB(); - - /** - * - */ - void setB(double val) throw(DOMException); - - /** - * - */ - double getC(); - - /** - * - */ - void setC(double val) throw(DOMException); - - /** - * - */ - double getD(); - - /** - * - */ - void setD(double val) throw(DOMException); - - /** - * - */ - double getE(); - - /** - * - */ - void setE(double val) throw(DOMException); - - /** - * - */ - double getF(); - - /** - * - */ - void setF(double val) throw(DOMException); - - - /** - * Return the result of postmultiplying this matrix with another. - */ - SVGMatrix multiply(const SVGMatrix &other); - - /** - * Calculate the inverse of this matrix - * - * - * The determinant of a 3x3 matrix E - * (let's use our own notation for a bit) - * - * A B C - * D E F - * G H I - * is - * AEI - AFH - BDI + BFG + CDH - CEG - * - * Since in our affine transforms, G and H==0 and I==1, - * this reduces to: - * AE - BD - * In SVG's naming scheme, that is: a * d - c * b . SIMPLE! - * - * In a similar method of attack, SVG's adjunct matrix is: - * - * d -c cf-ed - * -b a eb-af - * 0 0 ad-cb - * - * To get the inverse matrix, we divide the adjunct matrix by - * the determinant. Notice that(ad-cb)/(ad-cb)==1. Very cool. - * So what we end up with is this: - * - * a = d/(ad-cb) c = -c/(ad-cb) e =(cf-ed)/(ad-cb) - * b = -b/(ad-cb) d = a/(ad-cb) f =(eb-af)/(ad-cb) - * - * (Since this would be in all SVG-DOM implementations, - * somebody needed to document this! ^^) - * - */ - SVGMatrix inverse() throw(SVGException); - - /** - * Equivalent to multiplying by: - * | 1 0 x | - * | 0 1 y | - * | 0 0 1 | - * - */ - SVGMatrix translate(double x, double y); - - /** - * Equivalent to multiplying by: - * | scale 0 0 | - * | 0 scale 0 | - * | 0 0 1 | - * - */ - SVGMatrix scale(double scale); - - /** - * Equivalent to multiplying by: - * | scaleX 0 0 | - * | 0 scaleY 0 | - * | 0 0 1 | - * - */ - SVGMatrix scaleNonUniform(double scaleX, double scaleY); - - /** - * Equivalent to multiplying by: - * | cos(a) -sin(a) 0 | - * | sin(a) cos(a) 0 | - * | 0 0 1 | - * - */ - SVGMatrix rotate(double angle); - - /** - * Equivalent to multiplying by: - * | cos(a) -sin(a) 0 | - * | sin(a) cos(a) 0 | - * | 0 0 1 | - * In this case, angle 'a' is computed as the artangent - * of the slope y/x . It is negative if the slope is negative. - */ - SVGMatrix rotateFromVector(double x, double y) throw(SVGException); - - /** - * Equivalent to multiplying by: - * | -1 0 0 | - * | 0 1 0 | - * | 0 0 1 | - * - */ - SVGMatrix flipX(); - - /** - * Equivalent to multiplying by: - * | 1 0 0 | - * | 0 -1 0 | - * | 0 0 1 | - * - */ - SVGMatrix flipY(); - - /** - * | 1 tan(a) 0 | - * | 0 1 0 | - * | 0 0 1 | - * - */ - SVGMatrix skewX(double angle); - - /** - * Equivalent to multiplying by: - * | 1 0 0 | - * | tan(a) 1 0 | - * | 0 0 1 | - * - */ - SVGMatrix skewY(double angle); - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGMatrix(); - - /** - * - */ - SVGMatrix(double aArg, double bArg, double cArg, - double dArg, double eArg, double fArg); - - /** - * Copy constructor - */ - SVGMatrix(const SVGMatrix &other); - - /** - * - */ - ~SVGMatrix() {} - -protected: - -friend class SVGTransform; - - /* - * Set to the identify matrix - */ - void identity(); - - double a, b, c, d, e, f; - -}; - - -/*######################################################################### -## SVGNumber -#########################################################################*/ - -/** - * - */ -class SVGNumber -{ -public: - - /** - * - */ - double getValue(); - - /** - * - */ - void setValue(double val) throw(DOMException); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGNumber(); - - /** - * - */ - SVGNumber(const SVGNumber &other); - - /** - * - */ - ~SVGNumber(); - -protected: - - double value; - -}; - -/*######################################################################### -## SVGPoint -#########################################################################*/ - -/** - * - */ -class SVGPoint -{ -public: - - /** - * - */ - double getX(); - - /** - * - */ - void setX(double val) throw(DOMException); - - /** - * - */ - double getY(); - - /** - * - */ - void setY(double val) throw(DOMException); - - /** - * - */ - SVGPoint matrixTransform(const SVGMatrix &/*matrix*/); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGPoint(); - - /** - * - */ - SVGPoint(const SVGPoint &other); - - /** - * - */ - ~SVGPoint(); - -protected: - - double x, y; -}; - - -/*######################################################################### -## SVGPathSeg -#########################################################################*/ - -/** - * - */ -class SVGPathSeg -{ -public: - - /** - * Path Segment Types - */ - typedef enum - { - PATHSEG_UNKNOWN = 0, - PATHSEG_CLOSEPATH = 1, - PATHSEG_MOVETO_ABS = 2, - PATHSEG_MOVETO_REL = 3, - PATHSEG_LINETO_ABS = 4, - PATHSEG_LINETO_REL = 5, - PATHSEG_CURVETO_CUBIC_ABS = 6, - PATHSEG_CURVETO_CUBIC_REL = 7, - PATHSEG_CURVETO_QUADRATIC_ABS = 8, - PATHSEG_CURVETO_QUADRATIC_REL = 9, - PATHSEG_ARC_ABS = 10, - PATHSEG_ARC_REL = 11, - PATHSEG_LINETO_HORIZONTAL_ABS = 12, - PATHSEG_LINETO_HORIZONTAL_REL = 13, - PATHSEG_LINETO_VERTICAL_ABS = 14, - PATHSEG_LINETO_VERTICAL_REL = 15, - PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16, - PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17, - PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18, - PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19 - } PathSegmentType; - - /** - * - */ - unsigned short getPathSegType(); - - /** - * - */ - DOMString getPathSegTypeAsLetter(); - - /** - * From the various subclasses - */ - - /** - * - */ - double getX(); - - /** - * - */ - void setX(double val) throw(DOMException); - - /** - * - */ - double getX1(); - - /** - * - */ - void setX1(double val) throw(DOMException); - - /** - * - */ - double getX2(); - - /** - * - */ - void setX2(double val) throw(DOMException); - - /** - * - */ - double getY(); - - /** - * - */ - void setY(double val) throw(DOMException); - - /** - * - */ - double getY1(); - - /** - * - */ - void setY1(double val) throw(DOMException); - - /** - * - */ - double getY2(); - - /** - * - */ - void setY2(double val) throw(DOMException); - - /** - * - */ - double getR1(); - - /** - * - */ - void setR1(double val) throw(DOMException); - - /** - * - */ - double getR2(); - - /** - * - */ - void setR2(double val) throw(DOMException); - - /** - * - */ - double getAngle(); - - /** - * - */ - void setAngle(double val) throw(DOMException); - - /** - * - */ - bool getLargeArcFlag(); - - /** - * - */ - void setLargeArcFlag(bool val) throw(DOMException); - - /** - * - */ - bool getSweepFlag(); - - /** - * - */ - void setSweepFlag(bool val) throw(DOMException); - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGPathSeg(); - - /** - * - */ - SVGPathSeg(int typeArg); - - /** - * - */ - SVGPathSeg(const SVGPathSeg &other); - - /** - * - */ - SVGPathSeg &operator=(const SVGPathSeg &other); - - /** - * - */ - ~SVGPathSeg(); - -protected: - - void init(); - - void assign(const SVGPathSeg &other); - - int type; - double x, y, x1, y1, x2, y2; - double r1, r2; - double angle; - bool largeArcFlag; - bool sweepFlag; -}; - - -/*######################################################################### -## SVGPreserveAspectRatio -#########################################################################*/ - -/** - * - */ -class SVGPreserveAspectRatio -{ -public: - - - /** - * Alignment Types - */ - typedef enum - { - SVG_PRESERVEASPECTRATIO_UNKNOWN = 0, - SVG_PRESERVEASPECTRATIO_NONE = 1, - SVG_PRESERVEASPECTRATIO_XMINYMIN = 2, - SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3, - SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4, - SVG_PRESERVEASPECTRATIO_XMINYMID = 5, - SVG_PRESERVEASPECTRATIO_XMIDYMID = 6, - SVG_PRESERVEASPECTRATIO_XMAXYMID = 7, - SVG_PRESERVEASPECTRATIO_XMINYMAX = 8, - SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9, - SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10 - } AlignmentType; - - - /** - * Meet-or-slice Types - */ - typedef enum - { - SVG_MEETORSLICE_UNKNOWN = 0, - SVG_MEETORSLICE_MEET = 1, - SVG_MEETORSLICE_SLICE = 2 - } MeetOrSliceType; - - - /** - * - */ - unsigned short getAlign(); - - /** - * - */ - void setAlign(unsigned short val) throw(DOMException); - - /** - * - */ - unsigned short getMeetOrSlice(); - - /** - * - */ - void setMeetOrSlice(unsigned short val) throw(DOMException); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGPreserveAspectRatio(); - - /** - * - */ - SVGPreserveAspectRatio(const SVGPreserveAspectRatio &other); - - /** - * - */ - ~SVGPreserveAspectRatio(); - -protected: - - unsigned short align; - unsigned short meetOrSlice; - -}; - - - -/*######################################################################### -## SVGRect -#########################################################################*/ - -/** - * - */ -class SVGRect -{ -public: - - /** - * - */ - double getX(); - - /** - * - */ - void setX(double val) throw(DOMException); - - /** - * - */ - double getY(); - - /** - * - */ - void setY(double val) throw(DOMException); - - /** - * - */ - double getWidth(); - - /** - * - */ - void setWidth(double val) throw(DOMException); - - /** - * - */ - double getHeight(); - - /** - * - */ - void setHeight(double val) throw(DOMException); - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGRect(); - - /** - * - */ - SVGRect(const SVGRect &other); - - /** - * - */ - ~SVGRect(); - -protected: - - double x, y, width, height; - -}; - -/*######################################################################### -## SVGTransform -#########################################################################*/ - -/** - * - */ -class SVGTransform -{ -public: - - /** - * Transform Types - */ - typedef enum - { - SVG_TRANSFORM_UNKNOWN = 0, - SVG_TRANSFORM_MATRIX = 1, - SVG_TRANSFORM_TRANSLATE = 2, - SVG_TRANSFORM_SCALE = 3, - SVG_TRANSFORM_ROTATE = 4, - SVG_TRANSFORM_SKEWX = 5, - SVG_TRANSFORM_SKEWY = 6, - } TransformType; - - /** - * - */ - unsigned short getType(); - - - /** - * - */ - SVGMatrix getMatrix(); - - /** - * - */ - double getAngle(); - - /** - * - */ - void setMatrix(const SVGMatrix &matrixArg); - - /** - * - */ - void setTranslate(double tx, double ty); - - /** - * - */ - void setScale(double sx, double sy); - - /** - * - */ - void setRotate(double angleArg, double cx, double cy); - - /** - * - */ - void setSkewX(double angleArg); - - /** - * - */ - void setSkewY(double angleArg); - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGTransform(); - - /** - * - */ - SVGTransform(const SVGTransform &other); - - /** - * - */ - ~SVGTransform(); - -protected: - - int type; - double angle; - - SVGMatrix matrix; -}; - - - - -/*######################################################################### -## SVGUnitTypes -#########################################################################*/ - -/** - * - */ -class SVGUnitTypes -{ -public: - - /** - * Unit Types - */ - typedef enum - { - SVG_UNIT_TYPE_UNKNOWN = 0, - SVG_UNIT_TYPE_USERSPACEONUSE = 1, - SVG_UNIT_TYPE_OBJECTBOUNDINGBOX = 2 - } UnitType; - - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGUnitTypes(); - - /** - * - */ - ~SVGUnitTypes(); - -}; - - - - -/*######################################################################### -## SVGValue -#########################################################################*/ - -/** - * This is a helper class that will hold several types of data. It will - * be used in those situations where methods are common to different - * interfaces, except for the data type. This class holds the following: - * SVGAngle - * SVGBoolean - * SVGEnumeration - * SVGInteger - * SVGLength - * SVGNumber - * SVGPreserveAspectRatio - * SVGRect - * SVGString - */ -class SVGValue -{ -public: - - /** - * - */ - typedef enum - { - SVG_ANGLE, - SVG_BOOLEAN, - SVG_ENUMERATION, - SVG_INTEGER, - SVG_LENGTH, - SVG_NUMBER, - SVG_PRESERVE_ASPECT_RATIO, - SVG_RECT, - SVG_STRING, - } SVGValueType; - - /** - * Constructor - */ - SVGValue(); - - /** - * Copy constructor - */ - SVGValue(const SVGValue &other); - - /** - * Assignment - */ - SVGValue &operator=(const SVGValue &other); - - /** - * - */ - ~SVGValue(); - - //########################### - // TYPES - //########################### - - /** - * Angle - */ - SVGValue(const SVGAngle &v); - - SVGAngle angleValue(); - - /** - * Boolean - */ - SVGValue(bool v); - - bool booleanValue(); - - - /** - * Enumeration - */ - SVGValue(short v); - - short enumerationValue(); - - /** - * Integer - */ - SVGValue(long v); - - long integerValue(); - - /** - * Length - */ - SVGValue(const SVGLength &v); - - SVGLength lengthValue(); - - /** - * Number - */ - SVGValue(double v); - - double numberValue(); - - /** - * PathSegment - */ - SVGValue(const SVGPathSeg &v); - - SVGPathSeg pathDataValue(); - - - /** - * Points - */ - SVGValue(const SVGPoint &v); - - SVGPoint pointValue(); - - - /** - * PreserveAspectRatio - */ - SVGValue(const SVGPreserveAspectRatio &v); - - SVGPreserveAspectRatio preserveAspectRatioValue(); - - /** - * Rect - */ - SVGValue(const SVGRect &v); - - SVGRect rectValue(); - - /** - * String - */ - SVGValue(const DOMString &v); - - DOMString stringValue(); - - /** - * TransformList - */ - SVGValue(const SVGTransform &v); - - SVGTransform transformValue(); - - -private: - - void init(); - - void assign(const SVGValue &other); - - short type; - SVGAngle angleval; // SVGAngle - bool bval; // SVGBoolean - short eval; // SVGEnumeration - long ival; // SVGInteger - SVGLength lengthval; // SVGLength - double dval; // SVGNumber - SVGPathSeg segval; // SVGPathSeg - SVGPoint pointval; // SVGPoint - SVGPreserveAspectRatio parval; // SVGPreserveAspectRatio - SVGRect rval; // SVGRect - DOMString sval; // SVGString - SVGTransform transformval; // SVGTransform - -}; - - -/*######################################################################### -## SVGValueList -#########################################################################*/ - -/** - * THis is used to generify a bit the several different types of lists: - * - * SVGLengthList -> SVGValueList<SVGLength> - * SVGValueList -> SVGValueList<SVGNumber> - * SVGPathData -> SVGValueList<SVGPathSeg> - * SVGPoints -> SVGValueList<SVGPoint> - * SVGTransformList -> SVGValueList<SVGTransform> - */ -class SVGValueList -{ -public: - - /** - * - */ - typedef enum - { - SVG_LIST_LENGTH, - SVG_LIST_NUMBER, - SVG_LIST_PATHSEG, - SVG_LIST_POINT, - SVG_LIST_TRANSFORM - } SVGValueListTypes; - - /** - * - */ - unsigned long getNumberOfItems(); - - - /** - * - */ - void clear() throw(DOMException); - - /** - * - */ - SVGValue getItem(unsigned long index) throw(DOMException); - - /** - * - */ - SVGValue insertItemBefore(const SVGValue &newItem, - unsigned long index) - throw(DOMException, SVGException); - - /** - * - */ - SVGValue replaceItem(const SVGValue &newItem, - unsigned long index) - throw(DOMException, SVGException); - - /** - * - */ - SVGValue removeItem(unsigned long index) throw(DOMException); - - /** - * - */ - SVGValue appendItem(const SVGValue &newItem) - throw(DOMException, SVGException); - - /** - * Matrix - */ - SVGValue initialize(const SVGValue &newItem) - throw(DOMException, SVGException); - - /** - * Matrix - */ - SVGValue createSVGTransformFromMatrix(const SVGValue &matrix); - - /** - * Matrix - */ - SVGValue consolidate(); - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGValueList(); - - /** - * - */ - SVGValueList(const SVGValueList &other); - - /** - * - */ - ~SVGValueList(); - -protected: - - std::vector<SVGValue> items; - -}; - - - - - -/*######################################################################### -## SVGAnimatedValue -#########################################################################*/ - -/** - * This class is used to merge all of the "Animated" values, with only - * a different type, into a single API. This class subsumes the following: - * SVGAnimatedValue - * SVGAnimatedValue - * SVGAnimatedValue - * SVGAnimatedValue - * SVGAnimatedValue - * SVGAnimatedValue - * SVGAnimatedPathData - * SVGAnimatedPoints - * SVGAnimatedPreserveAspectRatio - * SVGAnimatedValue - * SVGAnimatedValue - */ -class SVGAnimatedValue -{ -public: - - /** - * - */ - SVGValue &getBaseVal(); - - /** - * - */ - void setBaseVal(const SVGValue &val) throw (DOMException); - - /** - * - */ - SVGValue &getAnimVal(); - - /** - * - */ - SVGAnimatedValue(); - - /** - * - */ - SVGAnimatedValue(const SVGValue &baseValue); - - /** - * - */ - SVGAnimatedValue(const SVGValue &baseValue, const SVGValue &animValue); - - /** - * - */ - SVGAnimatedValue(const SVGAnimatedValue &other); - - /** - * - */ - SVGAnimatedValue &operator=(const SVGAnimatedValue &other); - - /** - * - */ - SVGAnimatedValue &operator=(const SVGValue &baseVal); - - /** - * - */ - ~SVGAnimatedValue(); - -private: - - void init(); - - void assign(const SVGAnimatedValue &other); - - SVGValue baseVal; - - SVGValue animVal; - -}; - - -/*######################################################################### -## SVGAnimatedValueList -#########################################################################*/ - -/** - * This class is used to merge all of the "Animated" values, with only - * a different type, into a single API. This class subsumes the following: - * SVGAnimatedValueList - * SVGAnimatedValueList - * SVGAnimatedTransformList - */ -class SVGAnimatedValueList -{ -public: - - /** - * - */ - SVGValueList &getBaseVal(); - - /** - * - */ - void setBaseVal(const SVGValueList &val) throw (DOMException); - - /** - * - */ - SVGValueList &getAnimVal(); - - /** - * - */ - SVGAnimatedValueList(); - - /** - * - */ - SVGAnimatedValueList(const SVGValueList &baseValue); - - /** - * - */ - SVGAnimatedValueList(const SVGValueList &baseValue, const SVGValueList &animValue); - - /** - * - */ - SVGAnimatedValueList(const SVGAnimatedValueList &other); - - /** - * - */ - SVGAnimatedValueList &operator=(const SVGAnimatedValueList &other); - - /** - * - */ - SVGAnimatedValueList &operator=(const SVGValueList &baseVal); - - /** - * - */ - ~SVGAnimatedValueList(); - -private: - - void init(); - - void assign(const SVGAnimatedValueList &other); - - SVGValueList baseVal; - - SVGValueList animVal; - -}; - - - -/*######################################################################### -## SVGICCColor -#########################################################################*/ - -/** - * - */ -class SVGICCColor -{ -public: - - /** - * - */ - DOMString getColorProfile(); - - /** - * - */ - void setColorProfile(const DOMString &val) throw(DOMException); - - /** - * - */ - SVGValueList &getColors(); - - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGICCColor(); - - /** - * - */ - SVGICCColor(const SVGICCColor &other); - - /** - * - */ - ~SVGICCColor(); - -protected: - - DOMString colorProfile; - - SVGValueList colors; - -}; - - - -/*######################################################################### -## SVGColor -#########################################################################*/ - -/** - * - */ -class SVGColor : public css::CSSValue -{ -public: - - - /** - * Color Types - */ - typedef enum - { - SVG_COLORTYPE_UNKNOWN = 0, - SVG_COLORTYPE_RGBCOLOR = 1, - SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2, - SVG_COLORTYPE_CURRENTCOLOR = 3 - } ColorType; - - - /** - * - */ - unsigned short getColorType(); - - /** - * - */ - css::RGBColor getRgbColor(); - - /** - * - */ - SVGICCColor getIccColor(); - - - /** - * - */ - void setRGBColor(const DOMString& /*rgbColor*/) - throw(SVGException); - - /** - * - */ - void setRGBColorICCColor(const DOMString& /*rgbColor*/, - const DOMString& /*iccColor*/) - throw(SVGException); - - /** - * - */ - void setColor(unsigned short /*colorType*/, - const DOMString& /*rgbColor*/, - const DOMString& /*iccColor*/) - throw(SVGException); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGColor(); - - /** - * - */ - SVGColor(const SVGColor &other); - - /** - * - */ - ~SVGColor(); - -protected: - - int colorType; - -}; - - - -/*######################################################################### -## SVGPaint -#########################################################################*/ - -/** - * - */ -class SVGPaint : public SVGColor -{ -public: - - /** - * Paint Types - */ - typedef enum - { - SVG_PAINTTYPE_UNKNOWN = 0, - SVG_PAINTTYPE_RGBCOLOR = 1, - SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR = 2, - SVG_PAINTTYPE_NONE = 101, - SVG_PAINTTYPE_CURRENTCOLOR = 102, - SVG_PAINTTYPE_URI_NONE = 103, - SVG_PAINTTYPE_URI_CURRENTCOLOR = 104, - SVG_PAINTTYPE_URI_RGBCOLOR = 105, - SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR = 106, - SVG_PAINTTYPE_URI = 107 - } PaintType; - - - /** - * - */ - unsigned short getPaintType(); - - /** - * - */ - DOMString getUri(); - - /** - * - */ - void setUri(const DOMString& uriArg); - - /** - * - */ - void setPaint(unsigned short paintTypeArg, - const DOMString& uriArg, - const DOMString& /*rgbColor*/, - const DOMString& /*iccColor*/) - throw(SVGException); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGPaint(); - - /** - * - */ - SVGPaint(const SVGPaint &other); - - /** - * - */ - ~SVGPaint(); - -protected: - - unsigned int paintType; - DOMString uri; - -}; - - - - -//######################################################################## -//######################################################################## -//# I N T E R F A C E S -//######################################################################## -//######################################################################## - - - - - - - -/*######################################################################### -## SVGStylable -#########################################################################*/ - -/** - * - */ -class SVGStylable -{ -public: - - /** - * - */ - SVGAnimatedValue getClassName(); - - /** - * - */ - css::CSSStyleDeclaration getStyle(); - - - /** - * - */ - css::CSSValue getPresentationAttribute(const DOMString& /*name*/); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGStylable(); - - /** - * - */ - SVGStylable(const SVGStylable &other); - - /** - * - */ - ~SVGStylable(); - -protected: - - SVGAnimatedValue className; - css::CSSStyleDeclaration style; - -}; - - - - - -/*######################################################################### -## SVGLocatable -#########################################################################*/ - -/** - * - */ -class SVGLocatable -{ -public: - - /** - * - */ - SVGElementPtr getNearestViewportElement(); - - /** - * - */ - SVGElementPtr getFarthestViewportElement(); - - /** - * - */ - SVGRect getBBox(); - - /** - * - */ - SVGMatrix getCTM(); - - /** - * - */ - SVGMatrix getScreenCTM(); - - /** - * - */ - SVGMatrix getTransformToElement(const SVGElement &/*element*/) - throw(SVGException); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGLocatable(); - - /** - * - */ - SVGLocatable(const SVGLocatable &/*other*/); - - /** - * - */ - ~SVGLocatable(); - -protected: - - SVGRect bbox; - SVGMatrix ctm; - SVGMatrix screenCtm; - -}; - - -/*######################################################################### -## SVGTransformable -#########################################################################*/ - -/** - * - */ -class SVGTransformable : public SVGLocatable -{ -public: - - - /** - * - */ - SVGAnimatedValueList &getTransform(); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGTransformable(); - - /** - * - */ - SVGTransformable(const SVGTransformable &other); - - /** - * - */ - ~SVGTransformable(); - -protected: - - SVGAnimatedValueList transforms; -}; - - - -/*######################################################################### -## SVGTests -#########################################################################*/ - -/** - * - */ -class SVGTests -{ -public: - - /** - * - */ - SVGValueList &getRequiredFeatures(); - - /** - * - */ - SVGValueList &getRequiredExtensions(); - - /** - * - */ - SVGValueList &getSystemLanguage(); - - /** - * - */ - bool hasExtension(const DOMString& /*extension*/); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGTests(); - - /** - * - */ - SVGTests(const SVGTests &other); - - /** - * - */ - ~SVGTests(); - -protected: - - SVGValueList requiredFeatures; - SVGValueList requiredExtensions; - SVGValueList systemLanguage; - -}; - - - - - - -/*######################################################################### -## SVGLangSpace -#########################################################################*/ - -/** - * - */ -class SVGLangSpace -{ -public: - - - /** - * - */ - DOMString getXmlLang(); - - /** - * - */ - void setXmlLang(const DOMString &val) throw(DOMException); - - /** - * - */ - DOMString getXmlSpace(); - - /** - * - */ - void setXmlSpace(const DOMString &val) throw(DOMException); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGLangSpace(); - - /** - * - */ - SVGLangSpace(const SVGLangSpace &other); - - /** - * - */ - ~SVGLangSpace(); - -protected: - - DOMString xmlLang; - DOMString xmlSpace; - -}; - - - -/*######################################################################### -## SVGExternalResourcesRequired -#########################################################################*/ - -/** - * - */ -class SVGExternalResourcesRequired -{ -public: - - /** - * boolean - */ - SVGAnimatedValue getExternalResourcesRequired(); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGExternalResourcesRequired(); - - /** - * - */ - SVGExternalResourcesRequired(const SVGExternalResourcesRequired &other); - - /** - * - */ - ~SVGExternalResourcesRequired(); - -protected: - - SVGAnimatedValue required; //boolean - -}; - - - - - - - - - -/*######################################################################### -## SVGFitToViewBox -#########################################################################*/ - -/** - * - */ -class SVGFitToViewBox -{ -public: - - /** - * rect - */ - SVGAnimatedValue getViewBox(); - - /** - * preserveAspectRatio - */ - SVGAnimatedValue getPreserveAspectRatio(); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGFitToViewBox(); - - /** - * - */ - SVGFitToViewBox(const SVGFitToViewBox &other); - - /** - * - */ - ~SVGFitToViewBox(); - -protected: - - SVGAnimatedValue viewBox; //rect - SVGAnimatedValue preserveAspectRatio; - -}; - - -/*######################################################################### -## SVGZoomAndPan -#########################################################################*/ - -/** - * - */ -class SVGZoomAndPan -{ -public: - - /** - * Zoom and Pan Types - */ - typedef enum - { - SVG_ZOOMANDPAN_UNKNOWN = 0, - SVG_ZOOMANDPAN_DISABLE = 1, - SVG_ZOOMANDPAN_MAGNIFY = 2 - } ZoomAndPanType; - - /** - * - */ - unsigned short getZoomAndPan(); - - /** - * - */ - void setZoomAndPan(unsigned short val) throw(DOMException); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGZoomAndPan(); - - /** - * - */ - SVGZoomAndPan(const SVGZoomAndPan &other); - - /** - * - */ - ~SVGZoomAndPan(); - -protected: - - unsigned short zoomAndPan; - -}; - - - - - - -/*######################################################################### -## SVGViewSpec -#########################################################################*/ - -/** - * - */ -class SVGViewSpec : public SVGZoomAndPan, - public SVGFitToViewBox -{ -public: - - /** - * - */ - SVGValueList getTransform(); - - /** - * - */ - SVGElementPtr getViewTarget(); - - /** - * - */ - DOMString getViewBoxString(); - - /** - * - */ - DOMString getPreserveAspectRatioString(); - - /** - * - */ - DOMString getTransformString(); - - /** - * - */ - DOMString getViewTargetString(); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGViewSpec(); - - /** - * - */ - SVGViewSpec(const SVGViewSpec &other); - - /** - * - */ - ~SVGViewSpec(); - -protected: - - SVGElementPtr viewTarget; - SVGValueList transform; -}; - - -/*######################################################################### -## SVGURIReference -#########################################################################*/ - -/** - * - */ -class SVGURIReference -{ -public: - - /** - * string - */ - SVGAnimatedValue getHref(); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGURIReference(); - - /** - * - */ - SVGURIReference(const SVGURIReference &other); - - /** - * - */ - ~SVGURIReference(); - -protected: - - SVGAnimatedValue href; - -}; - - - - - - -/*######################################################################### -## SVGCSSRule -#########################################################################*/ - -/** - * - */ -class SVGCSSRule : public css::CSSRule -{ -public: - - - /** - * Additional CSS RuleType to support ICC color specifications - */ - typedef enum - { - COLOR_PROFILE_RULE = 7 - } ColorProfileRuleType; - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGCSSRule(); - - /** - * - */ - SVGCSSRule(const SVGCSSRule &other); - - /** - * - */ - ~SVGCSSRule(); - -}; - - - -/*######################################################################### -## SVGRenderingIntent -#########################################################################*/ - -/** - * - */ -class SVGRenderingIntent -{ -public: - - /** - * Rendering Intent Types - */ - typedef enum - { - RENDERING_INTENT_UNKNOWN = 0, - RENDERING_INTENT_AUTO = 1, - RENDERING_INTENT_PERCEPTUAL = 2, - RENDERING_INTENT_RELATIVE_COLORIMETRIC = 3, - RENDERING_INTENT_SATURATION = 4, - RENDERING_INTENT_ABSOLUTE_COLORIMETRIC = 5 - } RenderingIntentType; - - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGRenderingIntent(); - - /** - * - */ - SVGRenderingIntent(const SVGRenderingIntent &other); - - /** - * - */ - ~SVGRenderingIntent(); - -protected: - - unsigned short renderingIntentType; -}; - - - - - - - - - -/*######################################################################### -## SVGColorProfileRule -#########################################################################*/ - -/** - * - */ -class SVGColorProfileRule : public SVGCSSRule, - public SVGRenderingIntent -{ - -public: - - /** - * - */ - DOMString getSrc(); - - /** - * - */ - void setSrc(const DOMString &val) throw(DOMException); - - /** - * - */ - DOMString getName(); - - /** - * - */ - void setName(const DOMString &val) throw(DOMException); - - /** - * - */ - unsigned short getRenderingIntent(); - - /** - * - */ - void setRenderingIntent(unsigned short val) throw(DOMException); - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGColorProfileRule(); - - /** - * - */ - SVGColorProfileRule(const SVGColorProfileRule &other); - - /** - * - */ - ~SVGColorProfileRule(); - -protected: - - unsigned short renderingIntent; - DOMString src; - DOMString name; - -}; - - - -/*######################################################################### -## SVGFilterPrimitiveStandardAttributes -#########################################################################*/ - -/** - * - */ -class SVGFilterPrimitiveStandardAttributes : public SVGStylable -{ -public: - - /** - * length - */ - SVGAnimatedValue getX(); - - /** - * length - */ - SVGAnimatedValue getY(); - - /** - * length - */ - SVGAnimatedValue getWidth(); - - /** - * length - */ - SVGAnimatedValue getHeight(); - - /** - * string - */ - SVGAnimatedValue getResult(); - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGFilterPrimitiveStandardAttributes(); - - /** - * - */ - SVGFilterPrimitiveStandardAttributes( - const SVGFilterPrimitiveStandardAttributes &other); - - /** - * - */ - ~SVGFilterPrimitiveStandardAttributes(); - -protected: - - SVGAnimatedValue x; - SVGAnimatedValue y; - SVGAnimatedValue width; - SVGAnimatedValue height; - SVGAnimatedValue result; - -}; - - -/*######################################################################### -## SVGEvent -#########################################################################*/ - -/** - * - */ -class SVGEvent : events::Event -{ -public: - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGEvent(); - - /** - * - */ - SVGEvent(const SVGEvent &other); - - /** - * - */ - ~SVGEvent(); - -}; - - - - -/*######################################################################### -## SVGZoomEvent -#########################################################################*/ - -/** - * - */ -class SVGZoomEvent : events::UIEvent -{ -public: - - /** - * - */ - SVGRect getZoomRectScreen(); - - /** - * - */ - double getPreviousScale(); - - /** - * - */ - SVGPoint getPreviousTranslate(); - - /** - * - */ - double getNewScale(); - - /** - * - */ - SVGPoint getNewTranslate(); - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGZoomEvent(); - - /** - * - */ - SVGZoomEvent(const SVGZoomEvent &other); - - /** - * - */ - ~SVGZoomEvent(); - -protected: - - SVGRect zoomRectScreen; - double previousScale; - SVGPoint previousTranslate; - double newScale; - SVGPoint newTranslate; - -}; - - - -/*######################################################################### -## SVGElementInstance -#########################################################################*/ - -/** - * - */ -class SVGElementInstance : public events::EventTarget -{ -public: - - /** - * - */ - SVGElementPtr getCorrespondingElement(); - - /** - * - */ - SVGUseElementPtr getCorrespondingUseElement(); - - /** - * - */ - SVGElementInstance getParentNode(); - - /** - * Since we are using stack types and this is a circular definition, - * we will instead implement this as a global function below: - * SVGElementInstanceList getChildNodes(const SVGElementInstance instance); - */ - //SVGElementInstanceList getChildNodes(); - - /** - * - */ - SVGElementInstance getFirstChild(); - - /** - * - */ - SVGElementInstance getLastChild(); - - /** - * - */ - SVGElementInstance getPreviousSibling(); - - /** - * - */ - SVGElementInstance getNextSibling(); - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGElementInstance(); - - /** - * - */ - SVGElementInstance(const SVGElementInstance &other); - - /** - * - */ - ~SVGElementInstance(); - -protected: - - SVGElementPtr correspondingElement; - SVGUseElementPtr correspondingUseElement; - -}; - - - - - - -/*######################################################################### -## SVGElementInstanceList -#########################################################################*/ - -/** - * - */ -class SVGElementInstanceList -{ -public: - - /** - * - */ - unsigned long getLength(); - - /** - * - */ - SVGElementInstance item(unsigned long index); - - /** - * This static method replaces the circular definition of: - * SVGElementInstanceList SVGElementInstance::getChildNodes() - * - */ - static SVGElementInstanceList getChildNodes(const SVGElementInstance &/*instance*/); - - - //################## - //# Non-API methods - //################## - - /** - * - */ - SVGElementInstanceList(); - - /** - * - */ - SVGElementInstanceList(const SVGElementInstanceList &other); - - /** - * - */ - ~SVGElementInstanceList(); - -protected: - - std::vector<SVGElementInstance> items; - - -}; - - - - - - - - -//######################################################################## -//######################################################################## -//######################################################################## -//# D O M -//######################################################################## -//######################################################################## -//######################################################################## - - - - - -/*######################################################################### -## Types -#########################################################################*/ - -/** - * Bitmasks for has_an interface for SVGElement - */ -#define SVG_ANGLE 0x00000001 -#define SVG_ANIMATED_ANGLE 0x00000002 -#define SVG_ANIMATED_BOOLEAN 0x00000004 -#define SVG_ANIMATED_ENUMERATION 0x00000008 -#define SVG_ANIMATED_INTEGER 0x00000010 -#define SVG_ANIMATED_LENGTH 0x00000020 -#define SVG_ANIMATED_LENGTH_LIST 0x00000040 -#define SVG_ANIMATED_NUMBER 0x00000080 -#define SVG_ANIMATED_NUMBER_LIST 0x00000100 -#define SVG_ANIMATED_RECT 0x00000200 -#define SVG_ANIMATED_STRING 0x00000400 -#define SVG_COLOR 0x00000800 -#define SVG_CSS_RULE 0x00001000 -#define SVG_EXTERNAL_RESOURCES_REQUIRED 0x00002000 -#define SVG_FIT_TO_VIEWBOX 0x00004000 -#define SVG_ICCCOLOR 0x00008000 -#define SVG_LANG_SPACE 0x00010000 -#define SVG_LENGTH 0x00020000 -#define SVG_LENGTH_LIST 0x00040000 -#define SVG_LOCATABLE 0x00080000 -#define SVG_NUMBER 0x00100000 -#define SVG_NUMBER_LIST 0x00200000 -#define SVG_RECT 0x00400000 -#define SVG_RENDERING_INTENT 0x00800000 -#define SVG_STRING_LIST 0x01000000 -#define SVG_STYLABLE 0x02000000 -#define SVG_TESTS 0x04000000 -#define SVG_TRANSFORMABLE 0x08000000 -#define SVG_UNIT_TYPES 0x10000000 -#define SVG_URI_REFERENCE 0x20000000 -#define SVG_VIEW_SPEC 0x40000000 -#define SVG_ZOOM_AND_PAN 0x80000000 - -/** - * How many above? Quite handy - */ -#define SVG_NR_INTERFACES 32 - - -/** - * Enumerations for SVGElement types - */ -typedef enum -{ - SVG_A_ELEMENT = 0, - SVG_ALTGLYPH_ELEMENT, - SVG_ALTGLYPHDEF_ELEMENT, - SVG_ALTGLYPHITEM_ELEMENT, - SVG_ANIMATE_ELEMENT, - SVG_ANIMATECOLOR_ELEMENT, - SVG_ANIMATEMOTION_ELEMENT, - SVG_ANIMATETRANSFORM_ELEMENT, - SVG_CIRCLE_ELEMENT, - SVG_CLIPPATH_ELEMENT, - SVG_COLOR_PROFILE_ELEMENT, - SVG_CURSOR_ELEMENT, - SVG_DEFINITION_SRC_ELEMENT, - SVG_DEFS_ELEMENT, - SVG_DESC_ELEMENT, - SVG_ELLIPSE_ELEMENT, - SVG_FEBLEND_ELEMENT, - SVG_FECOLORMATRIX_ELEMENT, - SVG_FECOMPONENTTRANSFER_ELEMENT, - SVG_FECOMPOSITE_ELEMENT, - SVG_FECONVOLVEMATRIX_ELEMENT, - SVG_FEDIFFUSELIGHTING_ELEMENT, - SVG_FEDISPLACEMENTMAP_ELEMENT, - SVG_FEDISTANTLIGHT_ELEMENT, - SVG_FEFLOOD_ELEMENT, - SVG_FEFUNCA_ELEMENT, - SVG_FEFUNCB_ELEMENT, - SVG_FEFUNCG_ELEMENT, - SVG_FEFUNCR_ELEMENT, - SVG_FEGAUSSIANBLUR_ELEMENT, - SVG_FEIMAGE_ELEMENT, - SVG_FEMERGE_ELEMENT, - SVG_FEMERGENODE_ELEMENT, - SVG_FEMORPHOLOGY_ELEMENT, - SVG_FEOFFSET_ELEMENT, - SVG_FEPOINTLIGHT_ELEMENT, - SVG_FESPECULARLIGHTING_ELEMENT, - SVG_FESPOTLIGHT_ELEMENT, - SVG_FETILE_ELEMENT, - SVG_FETURBULENCE_ELEMENT, - SVG_FILTER_ELEMENT, - SVG_FONT_ELEMENT, - SVG_FONT_FACE_ELEMENT, - SVG_FONT_FACE_FORMAT_ELEMENT, - SVG_FONT_FACE_NAME_ELEMENT, - SVG_FONT_FACE_SRC_ELEMENT, - SVG_FONT_FACE_URI_ELEMENT, - SVG_FOREIGNOBJECT_ELEMENT, - SVG_G_ELEMENT, - SVG_GLYPH_ELEMENT, - SVG_GLYPHREF_ELEMENT, - SVG_HKERN_ELEMENT, - SVG_IMAGE_ELEMENT, - SVG_LINE_ELEMENT, - SVG_LINEARGRADIENT_ELEMENT, - SVG_MARKER_ELEMENT, - SVG_MASK_ELEMENT, - SVG_METADATA_ELEMENT, - SVG_MISSING_GLYPH_ELEMENT, - SVG_MPATH_ELEMENT, - SVG_PATH_ELEMENT, - SVG_PATTERN_ELEMENT, - SVG_POLYGON_ELEMENT, - SVG_POLYLINE_ELEMENT, - SVG_RADIALGRADIENT_ELEMENT, - SVG_RECT_ELEMENT, - SVG_SCRIPT_ELEMENT, - SVG_SET_ELEMENT, - SVG_STOP_ELEMENT, - SVG_STYLE_ELEMENT, - SVG_SVG_ELEMENT, - SVG_SWITCH_ELEMENT, - SVG_SYMBOL_ELEMENT, - SVG_TEXT_ELEMENT, - SVG_TEXTPATH_ELEMENT, - SVG_TITLE_ELEMENT, - SVG_TREF_ELEMENT, - SVG_TSPAN_ELEMENT, - SVG_USE_ELEMENT, - SVG_VIEW_ELEMENT, - SVG_VKERN_ELEMENT, - SVG_MAX_ELEMENT -} SVGElementType; - - - - -/** - * Look up the SVG Element type enum for a given string - * Return -1 if not found - */ -int svgElementStrToEnum(const char *str); - - -/** - * Return the string corresponding to a given SVG element type enum - * Return "unknown" if not found - */ -const char *svgElementEnumToStr(int type); - - - - -/*######################################################################### -## SVGElement -#########################################################################*/ - -/** - * All of the SVG DOM interfaces that correspond directly to elements in the SVG - * language(e.g., the SVGPathElement interface corresponds directly to the - * 'path' element in the language) are derivative from base class SVGElement. - */ -class SVGElement : public Element -{ -public: - - //#################################################################### - //# BASE METHODS FOR SVGElement - //#################################################################### - - /** - * Get the value of the id attribute on the given element. - */ - DOMString getId(); - - /** - * Set the value of the id attribute on the given element. - */ - void setId(const DOMString &val) throw(DOMException); - - /** - * Corresponds to attribute xml:base on the given element. - */ - DOMString getXmlBase(); - - /** - * Corresponds to attribute xml:base on the given element. - */ - void setXmlBase(const DOMString &val) throw(DOMException); - - /** - * The nearest ancestor 'svg' element. Null if the given element is the - * outermost 'svg' element. - */ - SVGElementPtr getOwnerSVGElement(); - - /** - * The element which established the current viewport. Often, the nearest - * ancestor 'svg' element. Null if the given element is the outermost 'svg' - * element. - */ - SVGElementPtr getViewportElement(); - - - - //#################################################################### - //#################################################################### - //# E L E M E N T S - //#################################################################### - //#################################################################### - - //#################################################################### - //# SVGAElement - //#################################################################### - - - /** - * - */ - SVGAnimatedValue getTarget(); - - - - //#################################################################### - //# SVGAltGlyphElement - //#################################################################### - - - /** - * Get the attribute glyphRef on the given element. - */ - DOMString getGlyphRef(); - - /** - * Set the attribute glyphRef on the given element. - */ - void setGlyphRef(const DOMString &val) throw(DOMException); - - /** - * Get the attribute format on the given element. - */ - DOMString getFormat(); - - /** - * Set the attribute format on the given element. - */ - void setFormat(const DOMString &val) throw(DOMException); - - - //#################################################################### - //# SVGAltGlyphDefElement - //#################################################################### - - //#################################################################### - //# SVGAltGlyphItemElement - //#################################################################### - - - //#################################################################### - //# SVGAnimateElement - //#################################################################### - - - //#################################################################### - //# SVGAnimateColorElement - //#################################################################### - - //#################################################################### - //# SVGAnimateMotionElement - //#################################################################### - - - //#################################################################### - //# SVGAnimateTransformElement - //#################################################################### - - - //#################################################################### - //# SVGAnimationElement - //#################################################################### - - - /** - * - */ - SVGElementPtr getTargetElement(); - - /** - * - */ - double getStartTime(); - - /** - * - */ - double getCurrentTime(); - - /** - * - */ - double getSimpleDuration() throw(DOMException); - - - - //#################################################################### - //# SVGCircleElement - //#################################################################### - - /** - * Corresponds to attribute cx on the given 'circle' element. - */ - SVGAnimatedValue getCx(); - - /** - * Corresponds to attribute cy on the given 'circle' element. - */ - SVGAnimatedValue getCy(); - - /** - * Corresponds to attribute r on the given 'circle' element. - */ - SVGAnimatedValue getR(); - - //#################################################################### - //# SVGClipPathElement - //#################################################################### - - - /** - * Corresponds to attribute clipPathUnits on the given 'clipPath' element. - * Takes one of the constants defined in SVGUnitTypes. - */ - SVGAnimatedValue getClipPathUnits(); - - - - //#################################################################### - //# SVGColorProfileElement - //#################################################################### - - - /** - * Get the attribute local on the given element. - */ - DOMString getLocal(); - - /** - * Set the attribute local on the given element. - */ - void setLocal(const DOMString &val) throw(DOMException); - - /** - * Get the attribute name on the given element. - */ - DOMString getName(); - - /** - * Set the attribute name on the given element. - */ - void setName(const DOMString &val) throw(DOMException); - - /** - * Set the attribute rendering-intent on the given element. - * The type of rendering intent, identified by one of the - * SVGRenderingIntent constants. - */ - unsigned short getRenderingIntent(); - - /** - * Get the attribute rendering-intent on the given element. - */ - void setRenderingIntent(unsigned short val) throw(DOMException); - - - //#################################################################### - //# SVGComponentTransferFunctionElement - //#################################################################### - - - /** - * Component Transfer Types - */ - typedef enum - { - SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0, - SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1, - SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2, - SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3, - SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4, - SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5 - } ComponentTransferType; - - - /** - * Corresponds to attribute type on the given element. Takes one\ - * of the Component Transfer Types. - * -- also in SVGCSSRule - */ - // SVGAnimatedValue getType(); - - /** - * Corresponds to attribute tableValues on the given element. - */ - SVGAnimatedValueList getTableValues(); - - /** - * Corresponds to attribute slope on the given element. - */ - SVGAnimatedValue getSlope(); - - /** - * Corresponds to attribute intercept on the given element. - */ - SVGAnimatedValue getIntercept(); - - /** - * Corresponds to attribute amplitude on the given element. - */ - SVGAnimatedValue getAmplitude(); - - /** - * Corresponds to attribute exponent on the given element. - */ - SVGAnimatedValue getExponent(); - - /** - * Corresponds to attribute offset on the given element. - */ - SVGAnimatedValue getOffset(); - - //#################################################################### - //# SVGCursorElement - //#################################################################### - - /** - * -- also in SVGRect - */ - // SVGAnimatedValue getX(); - - /** - * -- also in SVGRect - */ - // SVGAnimatedValue getY(); - - - //#################################################################### - //# SVGDefinitionSrcElement - //#################################################################### - - //#################################################################### - //# SVGDefsElement - //#################################################################### - - //#################################################################### - //# SVGDescElement - //#################################################################### - - //#################################################################### - //# SVGEllipseElement - //#################################################################### - - /** - * Corresponds to attribute cx on the given 'ellipse' element. - * -- also in Circle - */ - // SVGAnimatedValue getCx(); - - /** - * Corresponds to attribute cy on the given 'ellipse' element. - * -- also in Circle - */ - // SVGAnimatedValue getCy(); - - /** - * Corresponds to attribute rx on the given 'ellipse' element. - */ - SVGAnimatedValue getRx(); - - /** - * Corresponds to attribute ry on the given 'ellipse' element. - */ - SVGAnimatedValue getRy(); - - - //#################################################################### - //# SVGFEBlendElement - //#################################################################### - - /** - * Blend Mode Types - */ - typedef enum - { - SVG_FEBLEND_MODE_UNKNOWN = 0, - SVG_FEBLEND_MODE_NORMAL = 1, - SVG_FEBLEND_MODE_MULTIPLY = 2, - SVG_FEBLEND_MODE_SCREEN = 3, - SVG_FEBLEND_MODE_DARKEN = 4, - SVG_FEBLEND_MODE_LIGHTEN = 5 - } BlendModeType; - - /** - * Corresponds to attribute in on the given 'feBlend' element. - */ - SVGAnimatedValue getIn1(); - - /** - * Corresponds to attribute in2 on the given 'feBlend' element. - */ - SVGAnimatedValue getIn2(); - - /** - * Corresponds to attribute mode on the given 'feBlend' element. - * Takes one of the Blend Mode Types. - */ - SVGAnimatedValue getMode(); - - - //#################################################################### - //# SVGFEColorMatrixElement - //#################################################################### - - /** - * Color Matrix Types - */ - typedef enum - { - SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0, - SVG_FECOLORMATRIX_TYPE_MATRIX = 1, - SVG_FECOLORMATRIX_TYPE_SATURATE = 2, - SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3, - SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA = 4 - } ColorMatrixType; - - - /** - * Corresponds to attribute in on the given 'feColorMatrix' element. - * - also in feBlend - */ - // SVGAnimatedValue getIn1(); - - /** - * Corresponds to attribute type on the given 'feColorMatrix' element. - * Takes one of the Color Matrix Types. - * -- also in CSSRule - */ - // SVGAnimatedValue getType(); - - /** - * Corresponds to attribute values on the given 'feColorMatrix' element. - * Provides access to the contents of the values attribute. - */ - SVGAnimatedValueList getValues(); - - - //#################################################################### - //# SVGFEComponentTransferElement - //#################################################################### - - - /** - * Corresponds to attribute in on the given 'feComponentTransfer' element. - * -- also in feBlend - */ - // SVGAnimatedValue getIn1(); - - //#################################################################### - //# SVGFECompositeElement - //#################################################################### - - /** - * Composite Operators - */ - typedef enum - { - SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0, - SVG_FECOMPOSITE_OPERATOR_OVER = 1, - SVG_FECOMPOSITE_OPERATOR_IN = 2, - SVG_FECOMPOSITE_OPERATOR_OUT = 3, - SVG_FECOMPOSITE_OPERATOR_ATOP = 4, - SVG_FECOMPOSITE_OPERATOR_XOR = 5, - SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6 - } CompositeOperatorType; - - /** - * Corresponds to attribute in on the given 'feComposite' element. - * -- also in feBlend - */ - // SVGAnimatedValue getIn1(); - - /** - * Corresponds to attribute in2 on the given 'feComposite' element. - * -- also in feBlend - */ - // SVGAnimatedValue getIn2(); - - /** - * Corresponds to attribute operator on the given 'feComposite' element. - * Takes one of the Composite Operators. - */ - SVGAnimatedValue getOperator(); - - /** - * Corresponds to attribute k1 on the given 'feComposite' element. - */ - SVGAnimatedValue getK1(); - - /** - * Corresponds to attribute k2 on the given 'feComposite' element. - */ - SVGAnimatedValue getK2(); - - /** - * Corresponds to attribute k3 on the given 'feComposite' element. - */ - SVGAnimatedValue getK3(); - - /** - * Corresponds to attribute k4 on the given 'feComposite' element. - */ - SVGAnimatedValue getK4(); - - - //#################################################################### - //# SVGFEConvolveMatrixElement - //#################################################################### - - - /** - * Edge Mode Values - */ - typedef enum - { - SVG_EDGEMODE_UNKNOWN = 0, - SVG_EDGEMODE_DUPLICATE = 1, - SVG_EDGEMODE_WRAP = 2, - SVG_EDGEMODE_NONE = 3 - } EdgeModeType; - - - /** - * Corresponds to attribute order on the given 'feConvolveMatrix' element. - */ - SVGAnimatedValue getOrderX(); - - /** - * Corresponds to attribute order on the given 'feConvolveMatrix' element. - */ - SVGAnimatedValue getOrderY(); - - /** - * Corresponds to attribute kernelMatrix on the given element. - */ - SVGAnimatedValueList getKernelMatrix(); - - /** - * Corresponds to attribute divisor on the given 'feConvolveMatrix' element. - */ - SVGAnimatedValue getDivisor(); - - /** - * Corresponds to attribute bias on the given 'feConvolveMatrix' element. - */ - SVGAnimatedValue getBias(); - - /** - * Corresponds to attribute targetX on the given 'feConvolveMatrix' element. - */ - SVGAnimatedValue getTargetX(); - - /** - * Corresponds to attribute targetY on the given 'feConvolveMatrix' element. - */ - SVGAnimatedValue getTargetY(); - - /** - * Corresponds to attribute edgeMode on the given 'feConvolveMatrix' - * element. Takes one of the Edge Mode Types. - */ - SVGAnimatedValue getEdgeMode(); - - /** - * Corresponds to attribute kernelUnitLength on the - * given 'feConvolveMatrix' element. - */ - SVGAnimatedValue getKernelUnitLengthX(); - - /** - * Corresponds to attribute kernelUnitLength on the given - * 'feConvolveMatrix' element. - */ - SVGAnimatedValue getKernelUnitLengthY(); - - /** - * Corresponds to attribute preserveAlpha on the - * given 'feConvolveMatrix' element. - */ - SVGAnimatedValue getPreserveAlpha(); - - - - //#################################################################### - //# SVGFEDiffuseLightingElement - //#################################################################### - - - /** - * Corresponds to attribute in on the given 'feDiffuseLighting' element. - * -- also in feBlend - */ - // SVGAnimatedValue getIn1(); - - /** - * Corresponds to attribute surfaceScale on the given - * 'feDiffuseLighting' element. - */ - SVGAnimatedValue getSurfaceScale(); - - /** - * Corresponds to attribute diffuseConstant on the given - * 'feDiffuseLighting' element. - */ - SVGAnimatedValue getDiffuseConstant(); - - /** - * Corresponds to attribute kernelUnitLength on the given - * 'feDiffuseLighting' element. - */ - // SVGAnimatedValue getKernelUnitLengthX(); - - /** - * Corresponds to attribute kernelUnitLength on the given - * 'feDiffuseLighting' element. - */ - // SVGAnimatedValue getKernelUnitLengthY(); - - - - - //#################################################################### - //# SVGFEDisplacementMapElement - //#################################################################### - - - /** - * Channel Selectors - */ - typedef enum - { - SVG_CHANNEL_UNKNOWN = 0, - SVG_CHANNEL_R = 1, - SVG_CHANNEL_G = 2, - SVG_CHANNEL_B = 3, - SVG_CHANNEL_A = 4 - } ChannelSelector; - - /** - * - * -- also in feBlend - */ - // SVGAnimatedValue getIn1(); - - /** - * - * -- also in feBlend - */ - // SVGAnimatedValue getIn2(); - - - /** - * - */ - SVGAnimatedValue getScale(); - - /** - * - */ - SVGAnimatedValue getXChannelSelector(); - - /** - * - */ - SVGAnimatedValue getYChannelSelector(); - - //#################################################################### - //# SVGFEDistantLightElement - //#################################################################### - - - /** - * Corresponds to attribute azimuth on the given 'feDistantLight' element. - */ - SVGAnimatedValue getAzimuth(); - - - /** - * Corresponds to attribute elevation on the given 'feDistantLight' - * element - */ - SVGAnimatedValue getElevation(); - - - //#################################################################### - //# SVGFEFloodElement - //#################################################################### - - - /** - * - * -- also in feBlend - */ - // SVGAnimatedValue getIn1(); - - - //#################################################################### - //# SVGFEFuncAElement - //#################################################################### - - //#################################################################### - //# SVGFEFuncBElement - //#################################################################### - - //#################################################################### - //# SVGFEFuncGElement - //#################################################################### - - //#################################################################### - //# SVGFEFuncRElement - //#################################################################### - - - //#################################################################### - //# SVGFEGaussianBlurElement - //#################################################################### - - - /** - * - * -- also in feBlend - */ - // SVGAnimatedValue getIn1(); - - - /** - * - */ - SVGAnimatedValue getStdDeviationX(); - - /** - * - */ - SVGAnimatedValue getStdDeviationY(); - - - /** - * - */ - void setStdDeviation(double stdDeviationX, double stdDeviationY); - - - //#################################################################### - //# SVGFEImageElement - //#################################################################### - - - //#################################################################### - //# SVGFEMergeElement - //#################################################################### - - //#################################################################### - //# SVGFEMergeNodeElement - //#################################################################### - - //#################################################################### - //# SVGFEMorphologyElement - //#################################################################### - - - - /** - * Morphology Operators - */ - typedef enum - { - SVG_MORPHOLOGY_OPERATOR_UNKNOWN = 0, - SVG_MORPHOLOGY_OPERATOR_ERODE = 1, - SVG_MORPHOLOGY_OPERATOR_DILATE = 2 - } MorphologyOperatorType; - - - /** - * - * -- also in feBlend - */ - // SVGAnimatedValue getIn1(); - - - /** - * - */ - // SVGAnimatedValue getOperator(); - - /** - * - */ - SVGAnimatedValue getRadiusX(); - - /** - * - */ - SVGAnimatedValue getRadiusY(); - - //#################################################################### - //# SVGFEOffsetElement - //#################################################################### - - /** - * - * -- also in feBlend - */ - // SVGAnimatedValue getIn1(); - - /** - * - */ - SVGAnimatedValue getDx(); - - /** - * - */ - SVGAnimatedValue getDy(); - - - //#################################################################### - //# SVGFEPointLightElement - //#################################################################### - - /** - * Corresponds to attribute x on the given 'fePointLight' element. - */ - SVGAnimatedValue getX(); - - /** - * Corresponds to attribute y on the given 'fePointLight' element. - */ - SVGAnimatedValue getY(); - - /** - * Corresponds to attribute z on the given 'fePointLight' element. - */ - SVGAnimatedValue getZ(); - - //#################################################################### - //# SVGFESpecularLightingElement - //#################################################################### - - - /** - * - * -- also in feBlend - */ - // SVGAnimatedValue getIn1(); - - /** - * - */ - // SVGAnimatedValue getSurfaceScale(); - - /** - * - */ - SVGAnimatedValue getSpecularConstant(); - - /** - * - */ - SVGAnimatedValue getSpecularExponent(); - - - //#################################################################### - //# SVGFESpotLightElement - //#################################################################### - - /** - * Corresponds to attribute x on the given 'feSpotLight' element. - */ - // SVGAnimatedValue getX(); - - /** - * Corresponds to attribute y on the given 'feSpotLight' element. - */ - // SVGAnimatedValue getY(); - - /** - * Corresponds to attribute z on the given 'feSpotLight' element. - */ - // SVGAnimatedValue getZ(); - - /** - * Corresponds to attribute pointsAtX on the given 'feSpotLight' element. - */ - SVGAnimatedValue getPointsAtX(); - - /** - * Corresponds to attribute pointsAtY on the given 'feSpotLight' element. - */ - SVGAnimatedValue getPointsAtY(); - - /** - * Corresponds to attribute pointsAtZ on the given 'feSpotLight' element. - */ - SVGAnimatedValue getPointsAtZ(); - - /** - * Corresponds to attribute specularExponent on the - * given 'feSpotLight' element. - */ - // SVGAnimatedValue getSpecularExponent(); - - /** - * Corresponds to attribute limitingConeAngle on the - * given 'feSpotLight' element. - */ - SVGAnimatedValue getLimitingConeAngle(); - - - //#################################################################### - //# SVGFETileElement - //#################################################################### - - - /** - * - * -- also in feBlend - */ - // SVGAnimatedValue getIn1(); - - - //#################################################################### - //# SVGFETurbulenceElement - //#################################################################### - - - /** - * Turbulence Types - */ - typedef enum - { - SVG_TURBULENCE_TYPE_UNKNOWN = 0, - SVG_TURBULENCE_TYPE_FRACTALNOISE = 1, - SVG_TURBULENCE_TYPE_TURBULENCE = 2 - } TurbulenceType; - - /** - * Stitch Options - */ - typedef enum - { - SVG_STITCHTYPE_UNKNOWN = 0, - SVG_STITCHTYPE_STITCH = 1, - SVG_STITCHTYPE_NOSTITCH = 2 - } StitchOption; - - - - /** - * - */ - SVGAnimatedValue getBaseFrequencyX(); - - /** - * - */ - SVGAnimatedValue getBaseFrequencyY(); - - /** - * - */ - SVGAnimatedValue getNumOctaves(); - - /** - * - */ - SVGAnimatedValue getSeed(); - - /** - * - */ - SVGAnimatedValue getStitchTiles(); - - /** - * - */ - SVGAnimatedValue getType(); - - - - //#################################################################### - //# SVGFilterElement - //#################################################################### - - - /** - * Corresponds to attribute filterUnits on the given 'filter' element. Takes one - * of the constants defined in SVGUnitTypes. - */ - SVGAnimatedValue getFilterUnits(); - - /** - * Corresponds to attribute primitiveUnits on the given 'filter' element. Takes - * one of the constants defined in SVGUnitTypes. - */ - SVGAnimatedValue getPrimitiveUnits(); - - /** - * - */ - // SVGAnimatedValue getX(); - - /** - * Corresponds to attribute x on the given 'filter' element. - */ - // SVGAnimatedValue getY(); - - /** - * Corresponds to attribute y on the given 'filter' element. - */ - // SVGAnimatedValue getWidth(); - - /** - * Corresponds to attribute height on the given 'filter' element. - */ - // SVGAnimatedValue getHeight(); - - - /** - * Corresponds to attribute filterRes on the given 'filter' element. - * Contains the X component of attribute filterRes. - */ - SVGAnimatedValue getFilterResX(); - - /** - * Corresponds to attribute filterRes on the given 'filter' element. - * Contains the Y component(possibly computed automatically) - * of attribute filterRes. - */ - SVGAnimatedValue getFilterResY(); - - /** - * Sets the values for attribute filterRes. - */ - void setFilterRes(unsigned long filterResX, unsigned long filterResY); - - - //#################################################################### - //# SVGFontElement - //#################################################################### - - //#################################################################### - //# SVGFontFaceElement - //#################################################################### - - //#################################################################### - //# SVGFontFaceFormatElement - //#################################################################### - - //#################################################################### - //# SVGFontFaceNameElement - //#################################################################### - - //#################################################################### - //# SVGFontFaceSrcElement - //#################################################################### - - //#################################################################### - //# SVGFontFaceUriElement - //#################################################################### - - //#################################################################### - //# SVGForeignObjectElement - //#################################################################### - - /** - * - */ - // SVGAnimatedValue getX(); - - /** - * - */ - // SVGAnimatedValue getY(); - - /** - * - */ - // SVGAnimatedValue getWidth(); - - /** - * - */ - // SVGAnimatedValue getHeight(); - - - - //#################################################################### - //# SVGGlyphRefElement - //#################################################################### - - - /** - * Get the attribute glyphRef on the given element. - */ - // DOMString getGlyphRef(); - - /** - * Set the attribute glyphRef on the given element. - */ - // void setGlyphRef(const DOMString &val) throw(DOMException); - - /** - * Get the attribute format on the given element. - */ - // DOMString getFormat(); - - /** - * Set the attribute format on the given element. - */ - // void setFormat(const DOMString &val) throw(DOMException); - - /** - * Get the attribute x on the given element. - */ - // double getX(); - - /** - * Set the attribute x on the given element. - */ - // void setX(double val) throw(DOMException); - - /** - * Get the attribute y on the given element. - */ - // double getY(); - - /** - * Set the attribute y on the given element. - */ - // void setY(double val) throw(DOMException); - - /** - * Get the attribute dx on the given element. - */ - // double getDx(); - - /** - * Set the attribute dx on the given element. - */ - // void setDx(double val) throw(DOMException); - - /** - * Get the attribute dy on the given element. - */ - // double getDy(); - - /** - * Set the attribute dy on the given element. - */ - // void setDy(double val) throw(DOMException); - - - //#################################################################### - //# SVGGradientElement - //#################################################################### - - - /** - * Spread Method Types - */ - typedef enum - { - SVG_SPREADMETHOD_UNKNOWN = 0, - SVG_SPREADMETHOD_PAD = 1, - SVG_SPREADMETHOD_REFLECT = 2, - SVG_SPREADMETHOD_REPEAT = 3 - } SpreadMethodType; - - - /** - * Corresponds to attribute gradientUnits on the given element. - * Takes one of the constants defined in SVGUnitTypes. - */ - SVGAnimatedValue &getGradientUnits(); - - /** - * Corresponds to attribute gradientTransform on the given element. - */ - SVGAnimatedValueList &getGradientTransform(); - - /** - * Corresponds to attribute spreadMethod on the given element. - * One of the Spread Method Types. - */ - SVGAnimatedValue &getSpreadMethod(); - - - - //#################################################################### - //# SVGHKernElement - //#################################################################### - - //#################################################################### - //# SVGImageElement - //#################################################################### - - /** - * Corresponds to attribute x on the given 'image' element. - */ - // SVGAnimatedValue getX(); - - /** - * Corresponds to attribute y on the given 'image' element. - */ - // SVGAnimatedValue getY(); - - /** - * Corresponds to attribute width on the given 'image' element. - */ - // SVGAnimatedValue getWidth(); - - /** - * Corresponds to attribute height on the given 'image' element. - */ - // SVGAnimatedValue getHeight(); - - - /** - * Corresponds to attribute preserveAspectRatio on the given element. - */ - // SVGAnimatedPreserveAspectRatio getPreserveAspectRatio(); - - //#################################################################### - //# SVGLinearGradientElement - //#################################################################### - - /** - * Corresponds to attribute x1 on the given 'linearGradient' element. - */ - // SVGAnimatedValue getX1(); - - /** - * Corresponds to attribute y1 on the given 'linearGradient' element. - */ - // SVGAnimatedValue getY1(); - - /** - * Corresponds to attribute x2 on the given 'linearGradient' element. - */ - // SVGAnimatedValue getX2(); - - /** - * Corresponds to attribute y2 on the given 'linearGradient' element. - */ - // SVGAnimatedValue getY2(); - - - - //#################################################################### - //# SVGLineElement - //#################################################################### - - /** - * Corresponds to attribute x1 on the given 'line' element. - */ - // SVGAnimatedValue getX1(); - - /** - * Corresponds to attribute y1 on the given 'line' element. - */ - // SVGAnimatedValue getY1(); - - /** - * Corresponds to attribute x2 on the given 'line' element. - */ - // SVGAnimatedValue getX2(); - - /** - * Corresponds to attribute y2 on the given 'line' element. - */ - // SVGAnimatedValue getY2(); - - - //#################################################################### - //# SVGMarkerElement - //#################################################################### - - - /** - * Marker Unit Types - */ - typedef enum - { - SVG_MARKERUNITS_UNKNOWN = 0, - SVG_MARKERUNITS_USERSPACEONUSE = 1, - SVG_MARKERUNITS_STROKEWIDTH = 2 - } MarkerUnitType; - - /** - * Marker Orientation Types - */ - typedef enum - { - SVG_MARKER_ORIENT_UNKNOWN = 0, - SVG_MARKER_ORIENT_AUTO = 1, - SVG_MARKER_ORIENT_ANGLE = 2 - } MarkerOrientationType; - - - /** - * Corresponds to attribute refX on the given 'marker' element. - */ - SVGAnimatedValue getRefX(); - - /** - * Corresponds to attribute refY on the given 'marker' element. - */ - SVGAnimatedValue getRefY(); - - /** - * Corresponds to attribute markerUnits on the given 'marker' element. - * One of the Marker Units Types defined above. - */ - SVGAnimatedValue getMarkerUnits(); - - /** - * Corresponds to attribute markerWidth on the given 'marker' element. - */ - SVGAnimatedValue getMarkerWidth(); - - /** - * Corresponds to attribute markerHeight on the given 'marker' element. - */ - SVGAnimatedValue getMarkerHeight(); - - /** - * Corresponds to attribute orient on the given 'marker' element. - * One of the Marker Orientation Types defined above. - */ - SVGAnimatedValue getOrientType(); - - /** - * Corresponds to attribute orient on the given 'marker' element. - * If markerUnits is SVG_MARKER_ORIENT_ANGLE, the angle value for - * attribute orient; otherwise, it will be set to zero. - */ - SVGAnimatedValue getOrientAngle(); - - - /** - * Sets the value of attribute orient to 'auto'. - */ - void setOrientToAuto(); - - /** - * Sets the value of attribute orient to the given angle. - */ - void setOrientToAngle(const SVGAngle &angle); - - - //#################################################################### - //# SVGMaskElement - //#################################################################### - - - /** - * Corresponds to attribute maskUnits on the given 'mask' element. Takes one of - * the constants defined in SVGUnitTypes. - */ - SVGAnimatedValue getMaskUnits(); - - /** - * Corresponds to attribute maskContentUnits on the given 'mask' element. Takes - * one of the constants defined in SVGUnitTypes. - */ - SVGAnimatedValue getMaskContentUnits(); - - /** - * Corresponds to attribute x on the given 'mask' element. - */ - // SVGAnimatedValue getX(); - - /** - * Corresponds to attribute y on the given 'mask' element. - */ - // SVGAnimatedValue getY(); - - /** - * Corresponds to attribute width on the given 'mask' element. - */ - // SVGAnimatedValue getWidth(); - - /** - * Corresponds to attribute height on the given 'mask' element. - */ - // SVGAnimatedValue getHeight(); - - //#################################################################### - //# SVGMetadataElement - //#################################################################### - - //#################################################################### - //# SVGMissingGlyphElement - //#################################################################### - - - //#################################################################### - //# SVGMPathElement - //#################################################################### - - /** - * Corresponds to attribute pathLength on the given 'path' element. - */ - SVGAnimatedValue getPathLength(); - - /** - * Returns the user agent's computed value for the total length of the path using - * the user agent's distance-along-a-path algorithm, as a distance in the current - * user coordinate system. - */ - double getTotalLength(); - - /** - * Returns the(x,y) coordinate in user space which is distance units along the - * path, utilizing the user agent's distance-along-a-path algorithm. - */ - SVGPoint getPointAtLength(double distance); - - /** - * Returns the index into pathSegList which is distance units along the path, - * utilizing the user agent's distance-along-a-path algorithm. - */ - unsigned long getPathSegAtLength(double distance); - - /** - * Returns a stand-alone, parentless SVGPathSegClosePath object. - */ - SVGPathSeg createSVGPathSegClosePath(); - - /** - * Returns a stand-alone, parentless SVGPathSegMovetoAbs object. - */ - SVGPathSeg createSVGPathSegMovetoAbs(double x, double y); - - /** - * Returns a stand-alone, parentless SVGPathSegMovetoRel object. - */ - SVGPathSeg createSVGPathSegMovetoRel(double x, double y); - - /** - * Returns a stand-alone, parentless SVGPathSegLinetoAbs object. - */ - SVGPathSeg createSVGPathSegLinetoAbs(double x, double y); - - /** - * Returns a stand-alone, parentless SVGPathSegLinetoRel object. - */ - SVGPathSeg createSVGPathSegLinetoRel(double x, double y); - - /** - * Returns a stand-alone, parentless SVGPathSegCurvetoCubicAbs object. - */ - SVGPathSeg createSVGPathSegCurvetoCubicAbs(double x, double y, - double x1, double y1, double x2, double y2); - - /** - * Returns a stand-alone, parentless SVGPathSegCurvetoCubicRel object. - */ - SVGPathSeg createSVGPathSegCurvetoCubicRel(double x, double y, - double x1, double y1, double x2, double y2); - - /** - * Returns a stand-alone, parentless SVGPathSegCurvetoQuadraticAbs object. - */ - SVGPathSeg createSVGPathSegCurvetoQuadraticAbs(double x, double y, - double x1, double y1); - - /** - * Returns a stand-alone, parentless SVGPathSegCurvetoQuadraticRel object. - */ - SVGPathSeg createSVGPathSegCurvetoQuadraticRel(double x, double y, - double x1, double y1); - - /** - * Returns a stand-alone, parentless SVGPathSegArcAbs object. - */ - SVGPathSeg createSVGPathSegArcAbs(double x, double y, - double r1, double r2, double angle, - bool largeArcFlag, bool sweepFlag); - - /** - * Returns a stand-alone, parentless SVGPathSegArcRel object. - */ - SVGPathSeg createSVGPathSegArcRel(double x, double y, double r1, - double r2, double angle, bool largeArcFlag, - bool sweepFlag); - - /** - * Returns a stand-alone, parentless SVGPathSegLinetoHorizontalAbs object. - */ - SVGPathSeg createSVGPathSegLinetoHorizontalAbs(double x); - - /** - * Returns a stand-alone, parentless SVGPathSegLinetoHorizontalRel object. - */ - SVGPathSeg createSVGPathSegLinetoHorizontalRel(double x); - - /** - * Returns a stand-alone, parentless SVGPathSegLinetoVerticalAbs object. - */ - SVGPathSeg createSVGPathSegLinetoVerticalAbs(double y); - - /** - * Returns a stand-alone, parentless SVGPathSegLinetoVerticalRel object. - */ - SVGPathSeg createSVGPathSegLinetoVerticalRel(double y); - - /** - * Returns a stand-alone, parentless SVGPathSegCurvetoCubicSmoothAbs object. - */ - SVGPathSeg createSVGPathSegCurvetoCubicSmoothAbs(double x, double y, - double x2, double y2); - - /** - * Returns a stand-alone, parentless SVGPathSegCurvetoCubicSmoothRel object. - */ - SVGPathSeg createSVGPathSegCurvetoCubicSmoothRel(double x, double y, - double x2, double y2); - - /** - * Returns a stand-alone, parentless SVGPathSegCurvetoQuadraticSmoothAbs - * object. - */ - SVGPathSeg createSVGPathSegCurvetoQuadraticSmoothAbs(double x, double y); - - /** - * Returns a stand-alone, parentless SVGPathSegCurvetoQuadraticSmoothRel - * object. - */ - SVGPathSeg createSVGPathSegCurvetoQuadraticSmoothRel(double x, double y); - - //#################################################################### - //# SVGPathElement - //#################################################################### - - //#################################################################### - //# SVGPatternElement - //#################################################################### - - /** - * Corresponds to attribute patternUnits on the given 'pattern' element. - * Takes one of the constants defined in SVGUnitTypes. - */ - SVGAnimatedValue getPatternUnits(); - - /** - * Corresponds to attribute patternContentUnits on the given 'pattern' - * element. Takes one of the constants defined in SVGUnitTypes. - */ - SVGAnimatedValue getPatternContentUnits(); - - /** - * Corresponds to attribute patternTransform on the given 'pattern' element. - */ - SVGAnimatedValueList &getPatternTransform(); - - /** - * Corresponds to attribute x on the given 'pattern' element. - */ - // SVGAnimatedValue getX(); - - /** - * - */ - // SVGAnimatedValue getY(); - - /** - * Corresponds to attribute width on the given 'pattern' element. - */ - // SVGAnimatedValue getWidth(); - - /** - * Corresponds to attribute height on the given 'pattern' element. - */ - // SVGAnimatedValue getHeight(); - - - //#################################################################### - //# SVGPolyLineElement - //#################################################################### - - //#################################################################### - //# SVGPolygonElement - //#################################################################### - - //#################################################################### - //# SVGRadialGradientElement - //#################################################################### - - - /** - * Corresponds to attribute cx on the given 'radialGradient' element. - */ - // SVGAnimatedValue getCx(); - - - /** - * Corresponds to attribute cy on the given 'radialGradient' element. - */ - // SVGAnimatedValue getCy(); - - - /** - * Corresponds to attribute r on the given 'radialGradient' element. - */ - // SVGAnimatedValue getR(); - - - /** - * Corresponds to attribute fx on the given 'radialGradient' element. - */ - SVGAnimatedValue getFx(); - - - /** - * Corresponds to attribute fy on the given 'radialGradient' element. - */ - SVGAnimatedValue getFy(); - - - //#################################################################### - //# SVGRectElement - //#################################################################### - - /** - * Corresponds to attribute x on the given 'rect' element. - */ - // SVGAnimatedValue getX(); - - /** - * Corresponds to attribute y on the given 'rect' element. - */ - // SVGAnimatedValue getY(); - - /** - * Corresponds to attribute width on the given 'rect' element. - */ - // SVGAnimatedValue getWidth(); - - /** - * Corresponds to attribute height on the given 'rect' element. - */ - // SVGAnimatedValue getHeight(); - - - /** - * Corresponds to attribute rx on the given 'rect' element. - */ - // SVGAnimatedValue getRx(); - - /** - * Corresponds to attribute ry on the given 'rect' element. - */ - // SVGAnimatedValue getRy(); - - - //#################################################################### - //# SVGScriptElement - //#################################################################### - - /** - * - */ - // DOMString getType(); - - /** - * - */ - // void setType(const DOMString &val) throw(DOMException); - - //#################################################################### - //# SVGSetElement - //#################################################################### - - //#################################################################### - //# SVGStopElement - //#################################################################### - - - /** - * Corresponds to attribute offset on the given 'stop' element. - */ - // SVGAnimatedValue getOffset(); - - - //#################################################################### - //# SVGStyleElement - //#################################################################### - - /** - * Get the attribute xml:space on the given element. - */ - DOMString getXmlspace(); - - /** - * Set the attribute xml:space on the given element. - */ - void setXmlspace(const DOMString &val) throw(DOMException); - - /** - * Get the attribute type on the given 'style' element. - */ - // DOMString getType(); - - /** - * Set the attribute type on the given 'style' element. - */ - // void setType(const DOMString &val) throw(DOMException); - - /** - * Get the attribute media on the given 'style' element. - */ - DOMString getMedia(); - - /** - * Set the attribute media on the given 'style' element. - */ - void setMedia(const DOMString &val) throw(DOMException); - - /** - * Get the attribute title on the given 'style' element. - */ - DOMString getTitle(); - - /** - * Set the attribute title on the given 'style' element. - */ - void setTitle(const DOMString &val) throw(DOMException); - - //#################################################################### - //# SVGSymbolElement - //#################################################################### - - //#################################################################### - //# SVGSVGElement - //#################################################################### - - /** - * Corresponds to attribute x on the given 'svg' element. - */ - // SVGAnimatedValue getX(); - - /** - * Corresponds to attribute y on the given 'svg' element. - */ - // SVGAnimatedValue getY(); - - /** - * Corresponds to attribute width on the given 'svg' element. - */ - // SVGAnimatedValue getWidth(); - - /** - * Corresponds to attribute height on the given 'svg' element. - */ - // SVGAnimatedValue getHeight(); - - /** - * Get the attribute contentScriptType on the given 'svg' element. - */ - DOMString getContentScriptType(); - - /** - * Set the attribute contentScriptType on the given 'svg' element. - */ - void setContentScriptType(const DOMString &val) throw(DOMException); - - - /** - * Get the attribute contentStyleType on the given 'svg' element. - */ - DOMString getContentStyleType(); - - /** - * Set the attribute contentStyleType on the given 'svg' element. - */ - void setContentStyleType(const DOMString &val) throw(DOMException); - - /** - * The position and size of the viewport(implicit or explicit) that corresponds - * to this 'svg' element. When the user agent is actually rendering the content, - * then the position and size values represent the actual values when rendering. - * The position and size values are unitless values in the coordinate system of - * the parent element. If no parent element exists(i.e., 'svg' element - * represents the root of the document tree), if this SVG document is embedded as - * part of another document(e.g., via the HTML 'object' element), then the - * position and size are unitless values in the coordinate system of the parent - * document.(If the parent uses CSS or XSL layout, then unitless values - * represent pixel units for the current CSS or XSL viewport, as described in the - * CSS2 specification.) If the parent element does not have a coordinate system, - * then the user agent should provide reasonable default values for this attribute. - * */ - SVGRect getViewport(); - - /** - * Size of a pixel units(as defined by CSS2) along the x-axis of the viewport, - * which represents a unit somewhere in the range of 70dpi to 120dpi, and, on - * systems that support this, might actually match the characteristics of the - * target medium. On systems where it is impossible to know the size of a pixel, - * a suitable default pixel size is provided. - */ - double getPixelUnitToMillimeterX(); - - /** - * Corresponding size of a pixel unit along the y-axis of the viewport. - */ - double getPixelUnitToMillimeterY(); - - /** - * User interface(UI) events in DOM Level 2 indicate the screen positions at - * which the given UI event occurred. When the user agent actually knows the - * physical size of a "screen unit", this attribute will express that information; - * otherwise, user agents will provide a suitable default value such as .28mm. - */ - double getScreenPixelToMillimeterX(); - - /** - * Corresponding size of a screen pixel along the y-axis of the viewport. - */ - double getScreenPixelToMillimeterY(); - - - /** - * The initial view(i.e., before magnification and panning) of the current - * innermost SVG document fragment can be either the "standard" view(i.e., based - * on attributes on the 'svg' element such as fitBoxToViewport) or to a "custom" - * view(i.e., a hyperlink into a particular 'view' or other element - see - * Linking into SVG content: URI fragments and SVG views). If the initial view is - * the "standard" view, then this attribute is false. If the initial view is a - * "custom" view, then this attribute is true. - */ - bool getUseCurrentView(); - - /** - * Set the value above - */ - void setUseCurrentView(bool val) throw(DOMException); - - /** - * The definition of the initial view(i.e., before magnification and panning) of - * the current innermost SVG document fragment. The meaning depends on the - * situation: - * - * * If the initial view was a "standard" view, then: - * o the values for viewBox, preserveAspectRatio and zoomAndPan within - * currentView will match the values for the corresponding DOM attributes that - * are on SVGSVGElement directly - * o the values for transform and viewTarget within currentView will be null - * * If the initial view was a link into a 'view' element, then: - * o the values for viewBox, preserveAspectRatio and zoomAndPan within - * currentView will correspond to the corresponding attributes for the given - * 'view' element - * o the values for transform and viewTarget within currentView will be null - * * If the initial view was a link into another element(i.e., other than a - * 'view'), then: - * o the values for viewBox, preserveAspectRatio and zoomAndPan within - * currentView will match the values for the corresponding DOM attributes that - * are on SVGSVGElement directly for the closest ancestor 'svg' element - * o the values for transform within currentView will be null - * o the viewTarget within currentView will represent the target of the link - * * If the initial view was a link into the SVG document fragment using an SVG - * view specification fragment identifier(i.e., #svgView(...)), then: - * o the values for viewBox, preserveAspectRatio, zoomAndPan, transform and - * viewTarget within currentView will correspond to the values from the SVG view - * specification fragment identifier - * - */ - SVGViewSpec getCurrentView(); - - - /** - * This attribute indicates the current scale factor relative to the initial view - * to take into account user magnification and panning operations, as described - * under Magnification and panning. DOM attributes currentScale and - * currentTranslate are equivalent to the 2x3 matrix [a b c d e f] = - * [currentScale 0 0 currentScale currentTranslate.x currentTranslate.y]. If - * "magnification" is enabled(i.e., zoomAndPan="magnify"), then the effect is as - * if an extra transformation were placed at the outermost level on the SVG - * document fragment(i.e., outside the outermost 'svg' element). - */ - double getCurrentScale(); - - /** - * Set the value above. - */ - void setCurrentScale(double val) throw(DOMException); - - /** - * The corresponding translation factor that takes into account - * user "magnification". - */ - SVGPoint getCurrentTranslate(); - - /** - * Takes a time-out value which indicates that redraw shall not occur until:(a) - * the corresponding unsuspendRedraw(suspend_handle_id) call has been made,(b) - * an unsuspendRedrawAll() call has been made, or(c) its timer has timed out. In - * environments that do not support interactivity(e.g., print media), then - * redraw shall not be suspended. suspend_handle_id = - * suspendRedraw(max_wait_milliseconds) and unsuspendRedraw(suspend_handle_id) - * must be packaged as balanced pairs. When you want to suspend redraw actions as - * a collection of SVG DOM changes occur, then precede the changes to the SVG DOM - * with a method call similar to suspend_handle_id = - * suspendRedraw(max_wait_milliseconds) and follow the changes with a method call - * similar to unsuspendRedraw(suspend_handle_id). Note that multiple - * suspendRedraw calls can be used at once and that each such method call is - * treated independently of the other suspendRedraw method calls. - */ - unsigned long suspendRedraw(unsigned long max_wait_milliseconds); - - /** - * Cancels a specified suspendRedraw() by providing a unique suspend_handle_id. - */ - void unsuspendRedraw(unsigned long suspend_handle_id) throw(DOMException); - - /** - * Cancels all currently active suspendRedraw() method calls. This method is most - * useful at the very end of a set of SVG DOM calls to ensure that all pending - * suspendRedraw() method calls have been cancelled. - */ - void unsuspendRedrawAll(); - - /** - * In rendering environments supporting interactivity, forces the user agent to - * immediately redraw all regions of the viewport that require updating. - */ - void forceRedraw(); - - /** - * Suspends(i.e., pauses) all currently running animations that are defined - * within the SVG document fragment corresponding to this 'svg' element, causing - * the animation clock corresponding to this document fragment to stand still - * until it is unpaused. - */ - void pauseAnimations(); - - /** - * Unsuspends(i.e., unpauses) currently running animations that are defined - * within the SVG document fragment, causing the animation clock to continue from - * the time at which it was suspended. - */ - void unpauseAnimations(); - - /** - * Returns true if this SVG document fragment is in a paused state. - */ - bool animationsPaused(); - - /** - * Returns the current time in seconds relative to the start time for - * the current SVG document fragment. - */ - // double getCurrentTime(); - - /** - * Adjusts the clock for this SVG document fragment, establishing - * a new current time. - */ - void setCurrentTime(double seconds); - - /** - * Returns the list of graphics elements whose rendered content intersects the - * supplied rectangle, honoring the 'pointer-events' property value on each - * candidate graphics element. - */ - NodeList getIntersectionList(const SVGRect &rect, - const SVGElementPtr referenceElement); - - /** - * Returns the list of graphics elements whose rendered content is entirely - * contained within the supplied rectangle, honoring the 'pointer-events' - * property value on each candidate graphics element. - */ - NodeList getEnclosureList(const SVGRect &rect, - const SVGElementPtr referenceElement); - - /** - * Returns true if the rendered content of the given element intersects the - * supplied rectangle, honoring the 'pointer-events' property value on each - * candidate graphics element. - */ - bool checkIntersection(const SVGElementPtr element, const SVGRect &rect); - - /** - * Returns true if the rendered content of the given element is entirely - * contained within the supplied rectangle, honoring the 'pointer-events' - * property value on each candidate graphics element. - */ - bool checkEnclosure(const SVGElementPtr element, const SVGRect &rect); - - /** - * Unselects any selected objects, including any selections of text - * strings and type-in bars. - */ - void deselectAll(); - - /** - * Creates an SVGNumber object outside of any document trees. The object - * is initialized to a value of zero. - */ - SVGNumber createSVGNumber(); - - /** - * Creates an SVGLength object outside of any document trees. The object - * is initialized to the value of 0 user units. - */ - SVGLength createSVGLength(); - - /** - * Creates an SVGAngle object outside of any document trees. The object - * is initialized to the value 0 degrees(unitless). - */ - SVGAngle createSVGAngle(); - - /** - * Creates an SVGPoint object outside of any document trees. The object - * is initialized to the point(0,0) in the user coordinate system. - */ - SVGPoint createSVGPoint(); - - /** - * Creates an SVGMatrix object outside of any document trees. The object - * is initialized to the identity matrix. - */ - SVGMatrix createSVGMatrix(); - - /** - * Creates an SVGRect object outside of any document trees. The object - * is initialized such that all values are set to 0 user units. - */ - SVGRect createSVGRect(); - - /** - * Creates an SVGTransform object outside of any document trees. - * The object is initialized to an identity matrix transform - * (SVG_TRANSFORM_MATRIX). - */ - SVGTransform createSVGTransform(); - - /** - * Creates an SVGTransform object outside of any document trees. - * The object is initialized to the given matrix transform - * (i.e., SVG_TRANSFORM_MATRIX). - */ - SVGTransform createSVGTransformFromMatrix(const SVGMatrix &matrix); - - /** - * Searches this SVG document fragment(i.e., the search is restricted to a - * subset of the document tree) for an Element whose id is given by elementId. If - * an Element is found, that Element is returned. If no such element exists, - * returns null. Behavior is not defined if more than one element has this id. - */ - ElementPtr getElementById(const DOMString& elementId); - - - //#################################################################### - //# SVGTextElement - //#################################################################### - - - //#################################################################### - //# SVGTextContentElement - //#################################################################### - - - /** - * lengthAdjust Types - */ - typedef enum - { - LENGTHADJUST_UNKNOWN = 0, - LENGTHADJUST_SPACING = 1, - LENGTHADJUST_SPACINGANDGLYPHS = 2 - } LengthAdjustType; - - - /** - * Corresponds to attribute textLength on the given element. - */ - SVGAnimatedValue getTextLength(); - - - /** - * Corresponds to attribute lengthAdjust on the given element. The value must be - * one of the length adjust constants specified above. - */ - SVGAnimatedValue getLengthAdjust(); - - - /** - * Returns the total number of characters to be rendered within the current - * element. Includes characters which are included via a 'tref' reference. - */ - long getNumberOfChars(); - - /** - * The total sum of all of the advance values from rendering all of the - * characters within this element, including the advance value on the glyphs - *(horizontal or vertical), the effect of properties 'kerning', 'letter-spacing' - * and 'word-spacing' and adjustments due to attributes dx and dy on 'tspan' - * elements. For non-rendering environments, the user agent shall make reasonable - * assumptions about glyph metrics. - */ - double getComputedTextLength(); - - /** - * The total sum of all of the advance values from rendering the specified - * substring of the characters, including the advance value on the glyphs - *(horizontal or vertical), the effect of properties 'kerning', 'letter-spacing' - * and 'word-spacing' and adjustments due to attributes dx and dy on 'tspan' - * elements. For non-rendering environments, the user agent shall make reasonable - * assumptions about glyph metrics. - */ - double getSubStringLength(unsigned long charnum, unsigned long nchars) - throw(DOMException); - - /** - * Returns the current text position before rendering the character in the user - * coordinate system for rendering the glyph(s) that correspond to the specified - * character. The current text position has already taken into account the - * effects of any inter-character adjustments due to properties 'kerning', - * 'letter-spacing' and 'word-spacing' and adjustments due to attributes x, y, dx - * and dy. If multiple consecutive characters are rendered inseparably(e.g., as - * a single glyph or a sequence of glyphs), then each of the inseparable - * characters will return the start position for the first glyph. - */ - SVGPoint getStartPositionOfChar(unsigned long charnum) throw(DOMException); - - /** - * Returns the current text position after rendering the character in the user - * coordinate system for rendering the glyph(s) that correspond to the specified - * character. This current text position does not take into account the effects - * of any inter-character adjustments to prepare for the next character, such as - * properties 'kerning', 'letter-spacing' and 'word-spacing' and adjustments due - * to attributes x, y, dx and dy. If multiple consecutive characters are rendered - * inseparably(e.g., as a single glyph or a sequence of glyphs), then each of - * the inseparable characters will return the end position for the last glyph. - */ - SVGPoint getEndPositionOfChar(unsigned long charnum) throw(DOMException); - - /** - * Returns a tightest rectangle which defines the minimum and maximum X and Y - * values in the user coordinate system for rendering the glyph(s) that - * correspond to the specified character. The calculations assume that all glyphs - * occupy the full standard glyph cell for the font. If multiple consecutive - * characters are rendered inseparably(e.g., as a single glyph or a sequence of - * glyphs), then each of the inseparable characters will return the same extent. - */ - SVGRect getExtentOfChar(unsigned long charnum) throw(DOMException); - - /** - * Returns the rotation value relative to the current user coordinate system used - * to render the glyph(s) corresponding to the specified character. If multiple - * glyph(s) are used to render the given character and the glyphs each have - * different rotations(e.g., due to text-on-a-path), the user agent shall return - * an average value(e.g., the rotation angle at the midpoint along the path for - * all glyphs used to render this character). The rotation value represents the - * rotation that is supplemental to any rotation due to properties - * 'glyph-orientation-horizontal' and 'glyph-orientation-vertical'; thus, any - * glyph rotations due to these properties are not included into the returned - * rotation value. If multiple consecutive characters are rendered inseparably - *(e.g., as a single glyph or a sequence of glyphs), then each of the - * inseparable characters will return the same rotation value. - */ - double getRotationOfChar(unsigned long charnum) throw(DOMException); - - /** - * Returns the index of the character whose corresponding glyph cell bounding box - * contains the specified point. The calculations assume that all glyphs occupy - * the full standard glyph cell for the font. If no such character exists, a - * value of -1 is returned. If multiple such characters exist, the character - * within the element whose glyphs were rendered last(i.e., take into account - * any reordering such as for bidirectional text) is used. If multiple - * consecutive characters are rendered inseparably(e.g., as a single glyph or a - * sequence of glyphs), then the user agent shall allocate an equal percentage of - * the text advance amount to each of the contributing characters in determining - * which of the characters is chosen. - */ - long getCharNumAtPosition(const SVGPoint &point); - - /** - * Causes the specified substring to be selected just as if the user - * selected the substring interactively. - */ - void selectSubString(unsigned long charnum, unsigned long nchars) - throw(DOMException); - - - - - - //#################################################################### - //# SVGTextPathElement - //#################################################################### - - - /** - * textPath Method Types - */ - typedef enum - { - TEXTPATH_METHODTYPE_UNKNOWN = 0, - TEXTPATH_METHODTYPE_ALIGN = 1, - TEXTPATH_METHODTYPE_STRETCH = 2 - } TextPathMethodType; - - /** - * textPath Spacing Types - */ - typedef enum - { - TEXTPATH_SPACINGTYPE_UNKNOWN = 0, - TEXTPATH_SPACINGTYPE_AUTO = 1, - TEXTPATH_SPACINGTYPE_EXACT = 2 - } TextPathSpacingType; - - - /** - * Corresponds to attribute startOffset on the given 'textPath' element. - */ - SVGAnimatedValue getStartOffset(); - - /** - * Corresponds to attribute method on the given 'textPath' element. The value - * must be one of the method type constants specified above. - */ - SVGAnimatedValue getMethod(); - - /** - * Corresponds to attribute spacing on the given 'textPath' element. - * The value must be one of the spacing type constants specified above. - */ - SVGAnimatedValue getSpacing(); - - - //#################################################################### - //# SVGTextPositioningElement - //#################################################################### - - - /** - * Corresponds to attribute x on the given element. - */ - // SVGAnimatedValue getX(); - - /** - * Corresponds to attribute y on the given element. - */ - // SVGAnimatedValue getY(); - - /** - * Corresponds to attribute dx on the given element. - */ - // SVGAnimatedValue getDx(); - - /** - * Corresponds to attribute dy on the given element. - */ - // SVGAnimatedValue getDy(); - - - /** - * Corresponds to attribute rotate on the given element. - */ - SVGAnimatedValueList getRotate(); - - - //#################################################################### - //# SVGTitleElement - //#################################################################### - - //#################################################################### - //# SVGTRefElement - //#################################################################### - - //#################################################################### - //# SVGTSpanElement - //#################################################################### - - //#################################################################### - //# SVGSwitchElement - //#################################################################### - - //#################################################################### - //# SVGUseElement - //#################################################################### - - /** - * Corresponds to attribute x on the given 'use' element. - */ - // SVGAnimatedValue getX(); - - /** - * Corresponds to attribute y on the given 'use' element. - */ - // SVGAnimatedValue getY(); - - /** - * Corresponds to attribute width on the given 'use' element. - */ - // SVGAnimatedValue getWidth(); - - /** - * Corresponds to attribute height on the given 'use' element. - */ - // SVGAnimatedValue getHeight(); - - /** - * The root of the "instance tree". See description of SVGElementInstance for - * a discussion on the instance tree. - * */ - SVGElementInstance getInstanceRoot(); - - /** - * If the 'href' attribute is being animated, contains the current animated root - * of the "instance tree". If the 'href' attribute is not currently being - * animated, contains the same value as 'instanceRoot'. The root of the "instance - * tree". See description of SVGElementInstance for a discussion on the instance - * tree. - */ - SVGElementInstance getAnimatedInstanceRoot(); - - //#################################################################### - //# SVGVKernElement - //#################################################################### - - //#################################################################### - //# SVGViewElement - //#################################################################### - - - /** - * - */ - SVGValueList getViewTarget(); - - - - - //################## - //# Non-API methods - //################## - - - /** - * - */ - ~SVGElement() {} - - -}; - - - -/*######################################################################### -## SVGDocument -#########################################################################*/ - -/** - * When an 'svg' element is embedded inline as a component of a document from - * another namespace, such as when an 'svg' element is embedded inline within an - * XHTML document [XHTML], then an SVGDocument object will not exist; instead, - * the root object in the document object hierarchy will be a Document object of - * a different type, such as an HTMLDocument object. - * - * However, an SVGDocument object will indeed exist when the root element of the - * XML document hierarchy is an 'svg' element, such as when viewing a stand-alone - * SVG file(i.e., a file with MIME type "image/svg+xml"). In this case, the - * SVGDocument object will be the root object of the document object model - * hierarchy. - * - * In the case where an SVG document is embedded by reference, such as when an - * XHTML document has an 'object' element whose href attribute references an SVG - * document(i.e., a document whose MIME type is "image/svg+xml" and whose root - * element is thus an 'svg' element), there will exist two distinct DOM - * hierarchies. The first DOM hierarchy will be for the referencing document - *(e.g., an XHTML document). The second DOM hierarchy will be for the referenced - * SVG document. In this second DOM hierarchy, the root object of the document - * object model hierarchy is an SVGDocument object. - */ -class SVGDocument : public Document, - public events::DocumentEvent -{ -public: - - - /** - * The title of a document as specified by the title sub-element of the 'svg' - * root element(i.e., <svg><title>Here is the title</title>...</svg>) - */ - DOMString getTitle(); - - /** - * Returns the URI of the page that linked to this page. The value is an empty - * string if the user navigated to the page directly(not through a link, but, - * for example, via a bookmark). - */ - DOMString getReferrer(); - - /** - * The domain name of the server that served the document, or a null string if - * the server cannot be identified by a domain name. - */ - DOMString getDomain(); - - /** - * The complete URI of the document. - */ - DOMString getURL(); - - /** - * The root 'svg' element in the document hierarchy. - */ - SVGElementPtr getRootElement(); - - - //################## - //# Non-API methods - //################## - - /** - * - */ - ~SVGDocument() {} - -}; - - - -/*######################################################################### -## GetSVGDocument -#########################################################################*/ - -/** - * In the case where an SVG document is embedded by reference, such as when an - * XHTML document has an 'object' element whose href(or equivalent) attribute - * references an SVG document(i.e., a document whose MIME type is - * "image/svg+xml" and whose root element is thus an 'svg' element), the SVG user - * agent is required to implement the GetSVGDocument interface for the element - * which references the SVG document(e.g., the HTML 'object' or comparable - * referencing elements). - */ -class GetSVGDocument -{ -public: - - /** - * Returns the SVGDocument object for the referenced SVG document. - */ - SVGDocumentPtr getSVGDocument() - throw(DOMException); - - //################## - //# Non-API methods - //################## - - /** - * - */ - ~GetSVGDocument() {} - -}; - - - - - - - -} //namespace svg -} //namespace dom -} //namespace w3c -} //namespace org - -#endif // SEEN_SVG_H -/*######################################################################### -## E N D O F F I L E -#########################################################################*/ - diff --git a/src/dom/svgimpl.cpp b/src/dom/svgimpl.cpp index 87f43af81..4372e1b87 100644 --- a/src/dom/svgimpl.cpp +++ b/src/dom/svgimpl.cpp @@ -777,7 +777,7 @@ DOMString SVGSVGElementImpl::getAttribute(const DOMString& name) else if (name == "y") s = d2s(y.getAnimVal().getValue()); else - s = SVGElement::getAttribute(name); + s = SVGElementImpl::getAttribute(name); return s; } @@ -792,7 +792,7 @@ void SVGSVGElementImpl::setAttribute(const DOMString& name, x.getAnimVal().setValue(s2d(value)); else if (name == "y") y.getAnimVal().setValue(s2d(value)); - SVGElement::setAttribute(name, value); + SVGElementImpl::setAttribute(name, value); } 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/dropper-context.cpp b/src/dropper-context.cpp index 7dfe203ba..d513dd587 100644 --- a/src/dropper-context.cpp +++ b/src/dropper-context.cpp @@ -279,7 +279,7 @@ bool SPDropperContext::root_handler(GdkEvent* event) { // locale-sensitive printf is OK, since this goes to the UI, not into SVG gchar *alpha = g_strdup_printf(_(" alpha %.3g"), alpha_to_set); // where the color is picked, to show in the statusbar - gchar *where = this->dragging ? g_strdup_printf(_(", averaged with radius %d"), (int) rw) : g_strdup_printf(_(" under cursor")); + gchar *where = this->dragging ? g_strdup_printf(_(", averaged with radius %d"), (int) rw) : g_strdup_printf("%s", _(" under cursor")); // message, to show in the statusbar const gchar *message = this->dragging ? _("<b>Release mouse</b> to set color.") : _("<b>Click</b> to set fill, <b>Shift+click</b> to set stroke; <b>drag</b> to average color in area; with <b>Alt</b> to pick inverse color; <b>Ctrl+C</b> to copy the color under mouse to clipboard"); 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/ege-color-prof-tracker.cpp b/src/ege-color-prof-tracker.cpp index 53004a96d..eca90ecb7 100644 --- a/src/ege-color-prof-tracker.cpp +++ b/src/ege-color-prof-tracker.cpp @@ -110,6 +110,9 @@ typedef struct _ScreenTrack { GdkFilterReturn x11_win_filter(GdkXEvent *xevent, GdkEvent *event, gpointer data); void handle_property_change(GdkScreen* screen, const gchar* name); void add_x11_tracking_for_screen(GdkScreen* screen, ScreenTrack* screenTrack); +static void fire(GdkScreen* screen, gint monitor); +static void clear_profile( GdkScreen* screen, guint monitor ); +static void set_profile( GdkScreen* screen, guint monitor, const guint8* data, guint len ); #endif /* GDK_WINDOWING_X11 */ static guint signals[LAST_SIGNAL] = {0}; @@ -132,9 +135,6 @@ static void event_after_cb( GtkWidget* widget, GdkEvent* event, gpointer user_da static void target_hierarchy_changed_cb(GtkWidget* widget, GtkWidget* prev_top, gpointer user_data); static void target_screen_changed_cb(GtkWidget* widget, GdkScreen* prev_screen, gpointer user_data); static void screen_size_changed_cb(GdkScreen* screen, gpointer user_data); -static void fire(GdkScreen* screen, gint monitor); -static void clear_profile( GdkScreen* screen, guint monitor ); -static void set_profile( GdkScreen* screen, guint monitor, const guint8* data, guint len ); static void track_screen( GdkScreen* screen, EgeColorProfTracker* tracker ); G_DEFINE_TYPE(EgeColorProfTracker, ege_color_prof_tracker, G_TYPE_OBJECT); @@ -474,83 +474,6 @@ void screen_size_changed_cb(GdkScreen* screen, gpointer user_data) } } -void fire(GdkScreen* screen, gint monitor) -{ - GSList* curr = tracked_screens; - while ( curr ) { - ScreenTrack* track = (ScreenTrack*)curr->data; - if ( track->screen == screen) { - GSList* trackHook = track->trackers; - while ( trackHook ) { - EgeColorProfTracker* tracker = (EgeColorProfTracker*)(trackHook->data); - if ( (monitor == -1) || (tracker->private_data->_monitor == monitor) ) { - g_signal_emit( G_OBJECT(tracker), signals[CHANGED], 0 ); - } - trackHook = g_slist_next(trackHook); - } - } - curr = g_slist_next(curr); - } -} - -static void clear_profile( GdkScreen* screen, guint monitor ) -{ - GSList* curr = tracked_screens; - while ( curr && ((ScreenTrack*)curr->data)->screen != screen ) { - curr = g_slist_next(curr); - } - if ( curr ) { - ScreenTrack* track = (ScreenTrack*)curr->data; - guint i = 0; - GByteArray* previous = 0; - for ( i = track->profiles->len; i <= monitor; i++ ) { - g_ptr_array_add( track->profiles, 0 ); - } - previous = (GByteArray*)g_ptr_array_index( track->profiles, monitor ); - if ( previous ) { - g_byte_array_free( previous, TRUE ); - } - - track->profiles->pdata[monitor] = 0; - } -} - -static void set_profile( GdkScreen* screen, guint monitor, const guint8* data, guint len ) -{ - GSList* curr = tracked_screens; - while ( curr && ((ScreenTrack*)curr->data)->screen != screen ) { - curr = g_slist_next(curr); - } - if ( curr ) { - /* Something happened to a screen being tracked. */ - ScreenTrack* track = (ScreenTrack*)curr->data; - gint screenNum = gdk_screen_get_number(screen); - guint i = 0; - GByteArray* previous = 0; - GSList* abstracts = 0; - - for ( i = track->profiles->len; i <= monitor; i++ ) { - g_ptr_array_add( track->profiles, 0 ); - } - previous = (GByteArray*)g_ptr_array_index( track->profiles, monitor ); - if ( previous ) { - g_byte_array_free( previous, TRUE ); - } - - if ( data && len ) { - GByteArray* newBytes = g_byte_array_sized_new( len ); - newBytes = g_byte_array_append( newBytes, data, len ); - track->profiles->pdata[monitor] = newBytes; - } else { - track->profiles->pdata[monitor] = 0; - } - - for ( abstracts = abstract_trackers; abstracts; abstracts = g_slist_next(abstracts) ) { - g_signal_emit( G_OBJECT(abstracts->data), signals[MODIFIED], 0, screenNum, monitor ); - } - } -} - #ifdef GDK_WINDOWING_X11 GdkFilterReturn x11_win_filter(GdkXEvent *xevent, GdkEvent *event, @@ -692,4 +615,81 @@ void add_x11_tracking_for_screen(GdkScreen* screen, ScreenTrack* screenTrack) } } } + +void fire(GdkScreen* screen, gint monitor) +{ + GSList* curr = tracked_screens; + while ( curr ) { + ScreenTrack* track = (ScreenTrack*)curr->data; + if ( track->screen == screen) { + GSList* trackHook = track->trackers; + while ( trackHook ) { + EgeColorProfTracker* tracker = (EgeColorProfTracker*)(trackHook->data); + if ( (monitor == -1) || (tracker->private_data->_monitor == monitor) ) { + g_signal_emit( G_OBJECT(tracker), signals[CHANGED], 0 ); + } + trackHook = g_slist_next(trackHook); + } + } + curr = g_slist_next(curr); + } +} + +static void clear_profile( GdkScreen* screen, guint monitor ) +{ + GSList* curr = tracked_screens; + while ( curr && ((ScreenTrack*)curr->data)->screen != screen ) { + curr = g_slist_next(curr); + } + if ( curr ) { + ScreenTrack* track = (ScreenTrack*)curr->data; + guint i = 0; + GByteArray* previous = 0; + for ( i = track->profiles->len; i <= monitor; i++ ) { + g_ptr_array_add( track->profiles, 0 ); + } + previous = (GByteArray*)g_ptr_array_index( track->profiles, monitor ); + if ( previous ) { + g_byte_array_free( previous, TRUE ); + } + + track->profiles->pdata[monitor] = 0; + } +} + +static void set_profile( GdkScreen* screen, guint monitor, const guint8* data, guint len ) +{ + GSList* curr = tracked_screens; + while ( curr && ((ScreenTrack*)curr->data)->screen != screen ) { + curr = g_slist_next(curr); + } + if ( curr ) { + /* Something happened to a screen being tracked. */ + ScreenTrack* track = (ScreenTrack*)curr->data; + gint screenNum = gdk_screen_get_number(screen); + guint i = 0; + GByteArray* previous = 0; + GSList* abstracts = 0; + + for ( i = track->profiles->len; i <= monitor; i++ ) { + g_ptr_array_add( track->profiles, 0 ); + } + previous = (GByteArray*)g_ptr_array_index( track->profiles, monitor ); + if ( previous ) { + g_byte_array_free( previous, TRUE ); + } + + if ( data && len ) { + GByteArray* newBytes = g_byte_array_sized_new( len ); + newBytes = g_byte_array_append( newBytes, data, len ); + track->profiles->pdata[monitor] = newBytes; + } else { + track->profiles->pdata[monitor] = 0; + } + + for ( abstracts = abstract_trackers; abstracts; abstracts = g_slist_next(abstracts) ) { + g_signal_emit( G_OBJECT(abstracts->data), signals[MODIFIED], 0, screenNum, monitor ); + } + } +} #endif /* GDK_WINDOWING_X11 */ diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index 3cb03646a..ccc39fbef 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -43,6 +43,7 @@ #include "sp-object.h" #include "sp-root.h" #include "style.h" //style_write +#include "util/units.h" #include "extension/system.h" //IO @@ -543,13 +544,13 @@ gchar *document_interface_node(DocumentInterface *doc_interface, gchar *type, GE gdouble document_interface_document_get_width (DocumentInterface *doc_interface) { - return doc_interface->target.getDocument()->getWidth(); + return doc_interface->target.getDocument()->getWidth().value("px"); } gdouble document_interface_document_get_height (DocumentInterface *doc_interface) { - return doc_interface->target.getDocument()->getHeight(); + return doc_interface->target.getDocument()->getHeight().value("px"); } gchar *document_interface_document_get_css(DocumentInterface *doc_interface, GError ** error) diff --git a/src/extension/init.cpp b/src/extension/init.cpp index 1a163d4c2..2dde9eeb8 100644 --- a/src/extension/init.cpp +++ b/src/extension/init.cpp @@ -295,7 +295,7 @@ static void build_module_from_dir(gchar const *dirname) { if (!dirname) { - g_warning(_("Null external module directory name. Modules will not be loaded.")); + g_warning("%s", _("Null external module directory name. Modules will not be loaded.")); return; } 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/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index e6c400fb5..517d6fb9c 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -51,6 +51,8 @@ #include "svg-view.h" #include "svg-view-widget.h" +#include "util/units.h" + namespace Inkscape { namespace Extension { namespace Internal { @@ -254,6 +256,10 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u } SPDocument * doc = SPDocument::createNewDocFromMem(tmpSVGOutput[page_num-1].cstr(), strlen(tmpSVGOutput[page_num-1].cstr()), TRUE); + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().quantity, doc->getHeight().quantity)); + } return doc; } diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index b185d3348..d9489af31 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; @@ -3483,6 +3483,11 @@ Emf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) d.tri = trinfo_release_except_FC(d.tri); + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().quantity, doc->getHeight().quantity)); + } + return doc; } 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/filter/filter-file.cpp b/src/extension/internal/filter/filter-file.cpp index d569c6438..48e64f089 100644 --- a/src/extension/internal/filter/filter-file.cpp +++ b/src/extension/internal/filter/filter-file.cpp @@ -44,7 +44,7 @@ void Filter::filters_load_dir (gchar const * dirname, gchar * menuname) { if (!dirname) { - g_warning(_("Null external module directory name. Filters will not be loaded.")); + g_warning("%s", _("Null external module directory name. Filters will not be loaded.")); return; } diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index 87cf8a9cc..13267ee2b 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -102,6 +102,12 @@ GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) doc->getRoot()->appendChildRepr(image_node); Inkscape::GC::release(image_node); fit_canvas_to_drawing(doc); + + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().quantity, doc->getHeight().quantity)); + } + // restore undo, as now this document may be shown to the user if a bitmap was opened DocumentUndo::setUndoSensitive(doc, saved); } else { 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/image-resolution.cpp b/src/extension/internal/image-resolution.cpp index a9d33e831..b38b0ddc7 100644 --- a/src/extension/internal/image-resolution.cpp +++ b/src/extension/internal/image-resolution.cpp @@ -11,6 +11,7 @@ # include <config.h> #endif +#include "util/units.h" #include "image-resolution.h" #define IR_TRY_PNG 1 @@ -341,15 +342,9 @@ void ImageResolution::readmagick(char const *fn) { image.read(fn); } catch (...) {} Magick::Geometry geo = image.density(); - std::string type = image.magick(); - - if (type == "PNG") { // PNG only supports pixelspercentimeter - x_ = (double)geo.width() * 2.54; - y_ = (double)geo.height() * 2.54; - } else { - x_ = (double)geo.width(); - y_ = (double)geo.height(); - } + + x_ = Inkscape::Util::Quantity::convert((double)geo.width(), "pt", "px"); + y_ = Inkscape::Util::Quantity::convert((double)geo.height(), "pt", "px"); ok_ = true; } 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/pdf-input-cairo.cpp b/src/extension/internal/pdf-input-cairo.cpp index c2f2b43a5..adac0d6c9 100644 --- a/src/extension/internal/pdf-input-cairo.cpp +++ b/src/extension/internal/pdf-input-cairo.cpp @@ -23,6 +23,10 @@ #include "extension/input.h" #include "dialogs/dialog-events.h" #include "document.h" +#include "sp-root.h" +#include "util/units.h" + +#include <2geom/rect.h> #include "inkscape.h" @@ -491,7 +495,7 @@ bool PdfImportCairoDialog::_onDraw(const Cairo::RefPtr<Cairo::Context>& cr) { */ void PdfImportCairoDialog::_setPreviewPage(int page) { - PopplerPage *_previewed_page = poppler_document_get_page(_poppler_doc, page); + PopplerPage *_previewed_page = poppler_document_get_page(_poppler_doc, page-1); // Try to get a thumbnail from the PDF if possible if (!_render_thumb) { @@ -620,6 +624,11 @@ PdfInputCairo::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { SPDocument * doc = SPDocument::createNewDocFromMem(output->c_str(), output->length(), TRUE); + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().quantity, doc->getHeight().quantity)); + } + delete output; g_object_unref(page); g_object_unref(document); diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index b04c9782f..213550688 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -46,6 +46,7 @@ #include "document-private.h" #include "document-undo.h" #include "inkscape.h" +#include "util/units.h" #include "dialogs/dialog-events.h" #include <gtk/gtk.h> @@ -747,6 +748,11 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) { delete pdf_doc; delete dlg; + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().quantity, doc->getHeight().quantity)); + } + // Restore undo DocumentUndo::setUndoSensitive(doc, saved); 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/vsd-input.cpp b/src/extension/internal/vsd-input.cpp index 12e5150cb..42a9e3d41 100644 --- a/src/extension/internal/vsd-input.cpp +++ b/src/extension/internal/vsd-input.cpp @@ -39,6 +39,7 @@ #include "document-private.h" #include "document-undo.h" #include "inkscape.h" +#include "util/units.h" #include "dialogs/dialog-events.h" #include <gtk/gtk.h> @@ -254,6 +255,12 @@ SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u } SPDocument * doc = SPDocument::createNewDocFromMem(tmpSVGOutput[page_num-1].cstr(), strlen(tmpSVGOutput[page_num-1].cstr()), TRUE); + + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().quantity, doc->getHeight().quantity)); + } + return doc; } diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index 451d94c0e..e7dfa46d7 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 @@ -3171,6 +3171,11 @@ Wmf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) d.tri = trinfo_release_except_FC(d.tri); + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().quantity, doc->getHeight().quantity)); + } + return doc; } 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/extension/internal/wpg-input.cpp b/src/extension/internal/wpg-input.cpp index cb1677547..ac86a6171 100644 --- a/src/extension/internal/wpg-input.cpp +++ b/src/extension/internal/wpg-input.cpp @@ -48,6 +48,8 @@ #include "extension/system.h" #include "extension/input.h" #include "document.h" +#include "sp-root.h" +#include "util/units.h" #include <cstring> // Take a guess and fallback to 0.1.x if no configure has run @@ -109,6 +111,12 @@ SPDocument *WpgInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u //printf("I've got a doc: \n%s", painter.document.c_str()); SPDocument * doc = SPDocument::createNewDocFromMem(output.cstr(), strlen(output.cstr()), TRUE); + + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().quantity, doc->getHeight().quantity)); + } + delete input; return doc; } diff --git a/src/extension/system.cpp b/src/extension/system.cpp index f7fd48b3f..a4c370f4c 100644 --- a/src/extension/system.cpp +++ b/src/extension/system.cpp @@ -124,7 +124,7 @@ SPDocument *open(Extension *key, gchar const *filename) if ( inkscape_use_gui() ) { sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); } else { - g_warning(_("Format autodetect failed. The file is being opened as SVG.")); + g_warning("%s", _("Format autodetect failed. The file is being opened as SVG.")); } } diff --git a/src/file.cpp b/src/file.cpp index 68e229e62..b19fe21ff 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -74,6 +74,8 @@ #include <glibmm/i18n.h> #include <glibmm/miscutils.h> +#include <string> + using Inkscape::DocumentUndo; #ifdef WITH_GNOME_VFS @@ -124,7 +126,7 @@ static void sp_file_add_recent(gchar const *uri) /** * Create a blank document and add it to the desktop */ -SPDesktop *sp_file_new(const Glib::ustring &templ) +SPDesktop *sp_file_new(const std::string &templ) { SPDocument *doc = SPDocument::createNewDoc( !templ.empty() ? templ.c_str() : 0 , TRUE, true ); g_return_val_if_fail(doc != NULL, NULL); @@ -138,25 +140,19 @@ SPDesktop *sp_file_new(const Glib::ustring &templ) DocumentUndo::clearUndo(doc); } + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().quantity, doc->getHeight().quantity)); + } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) { + if (desktop) desktop->setWaitingCursor(); - } - SPDocument *existing = desktop ? sp_desktop_document(desktop) : NULL; - - if (existing && existing->virgin) { - // 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()); - } 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. - g_return_val_if_fail(dtw != NULL, NULL); - sp_create_window(dtw, TRUE); - desktop = static_cast<SPDesktop *>(dtw->view); - } + SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); // TODO this will trigger broken link warnings, etc. + g_return_val_if_fail(dtw != NULL, NULL); + sp_create_window(dtw, TRUE); + desktop = static_cast<SPDesktop *>(dtw->view); doc->doUnref(); @@ -166,6 +162,9 @@ SPDesktop *sp_file_new(const Glib::ustring &templ) #ifdef WITH_DBUS Inkscape::Extension::Dbus::dbus_init_desktop_interface(desktop); #endif + + if (desktop) + desktop->clearWaitingCursor(); return desktop; } @@ -220,7 +219,7 @@ SPDesktop* sp_file_new_default() { Glib::ustring templateUri = sp_file_default_template_uri(); SPDesktop* desk = sp_file_new(sp_file_default_template_uri()); - rdf_add_from_preferences( SP_ACTIVE_DOCUMENT ); + //rdf_add_from_preferences( SP_ACTIVE_DOCUMENT ); return desk; } @@ -291,7 +290,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/file.h b/src/file.h index 682ca422e..7f80f3645 100644 --- a/src/file.h +++ b/src/file.h @@ -16,6 +16,7 @@ */ #include <glibmm/ustring.h> +#include <string> #include "extension/system.h" class SPDesktop; @@ -43,7 +44,7 @@ Glib::ustring sp_file_default_template_uri(); * Creates a new Inkscape document and window. * Return value is a pointer to the newly created desktop. */ -SPDesktop* sp_file_new (const Glib::ustring &templ); +SPDesktop* sp_file_new (const std::string &templ); SPDesktop* sp_file_new_default (void); /*###################### diff --git a/src/filters/componenttransfer-funcnode.cpp b/src/filters/componenttransfer-funcnode.cpp index 7c5191700..7c7375802 100644 --- a/src/filters/componenttransfer-funcnode.cpp +++ b/src/filters/componenttransfer-funcnode.cpp @@ -30,10 +30,37 @@ #define SP_MACROS_SILENT #include "macros.h" + +#include "sp-factory.h" + +namespace { + SPObject* createFuncR() { + return new SPFeFuncNode(SPFeFuncNode::R); + } + + SPObject* createFuncG() { + return new SPFeFuncNode(SPFeFuncNode::G); + } + + SPObject* createFuncB() { + return new SPFeFuncNode(SPFeFuncNode::B); + } + + SPObject* createFuncA() { + return new SPFeFuncNode(SPFeFuncNode::A); + } + + bool funcRRegistered = SPFactory::instance().registerObject("svg:feFuncR", createFuncR); + bool funcGRegistered = SPFactory::instance().registerObject("svg:feFuncG", createFuncG); + bool funcBRegistered = SPFactory::instance().registerObject("svg:feFuncB", createFuncB); + bool funcARegistered = SPFactory::instance().registerObject("svg:feFuncA", createFuncA); +} + + /* FeFuncNode class */ -SPFeFuncNode::SPFeFuncNode() +SPFeFuncNode::SPFeFuncNode(SPFeFuncNode::Channel channel) : SPObject(), type(Inkscape::Filters::COMPONENTTRANSFER_TYPE_IDENTITY), - slope(1), intercept(0), amplitude(1), exponent(1), offset(0) { + slope(1), intercept(0), amplitude(1), exponent(1), offset(0), channel(channel) { } SPFeFuncNode::~SPFeFuncNode() { diff --git a/src/filters/componenttransfer-funcnode.h b/src/filters/componenttransfer-funcnode.h index a5f813e1e..4f9b8de2e 100644 --- a/src/filters/componenttransfer-funcnode.h +++ b/src/filters/componenttransfer-funcnode.h @@ -18,32 +18,15 @@ #include "sp-object.h" #include "display/nr-filter-component-transfer.h" -//#define SP_TYPE_FEFUNCR (sp_fefuncR_get_type()) -//#define SP_TYPE_FEFUNCG (sp_fefuncG_get_type()) -//#define SP_TYPE_FEFUNCB (sp_fefuncB_get_type()) -//#define SP_TYPE_FEFUNCA (sp_fefuncA_get_type()) - -// CPPIFY: Casting macros buggy, as these aren't classes. -//#define SP_IS_FEFUNCR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEFUNCR)) -//#define SP_IS_FEFUNCG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEFUNCG)) -//#define SP_IS_FEFUNCB(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEFUNCB)) -//#define SP_IS_FEFUNCA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEFUNCA)) - #define SP_FEFUNCNODE(obj) (dynamic_cast<SPFeFuncNode*>((SPObject*)obj)) -//#define SP_IS_FEFUNCR(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPFeFuncNode))) -//#define SP_IS_FEFUNCG(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPFeFuncNode))) -//#define SP_IS_FEFUNCB(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPFeFuncNode))) -//#define SP_IS_FEFUNCA(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPFeFuncNode))) - -#define SP_IS_FEFUNCR(obj) (dynamic_cast<const SPFeFuncNode*>((SPObject*)obj) != NULL) -#define SP_IS_FEFUNCG(obj) (dynamic_cast<const SPFeFuncNode*>((SPObject*)obj) != NULL) -#define SP_IS_FEFUNCB(obj) (dynamic_cast<const SPFeFuncNode*>((SPObject*)obj) != NULL) -#define SP_IS_FEFUNCA(obj) (dynamic_cast<const SPFeFuncNode*>((SPObject*)obj) != NULL) - class SPFeFuncNode : public SPObject { public: - SPFeFuncNode(); + enum Channel { + R, G, B, A + }; + + SPFeFuncNode(Channel channel); virtual ~SPFeFuncNode(); Inkscape::Filters::FilterComponentTransferType type; @@ -53,6 +36,7 @@ public: double amplitude; double exponent; double offset; + Channel channel; protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); diff --git a/src/filters/componenttransfer.cpp b/src/filters/componenttransfer.cpp index 96d1ea0bf..610b3dd02 100644 --- a/src/filters/componenttransfer.cpp +++ b/src/filters/componenttransfer.cpp @@ -65,12 +65,26 @@ static void sp_feComponentTransfer_children_modified(SPFeComponentTransfer *sp_c bool set[4] = {false, false, false, false}; SPObject* node = sp_componenttransfer->children; for(;node;node=node->next){ - int i=4; - if (SP_IS_FEFUNCR(node)) i=0; - if (SP_IS_FEFUNCG(node)) i=1; - if (SP_IS_FEFUNCB(node)) i=2; - if (SP_IS_FEFUNCA(node)) i=3; - if (i==4) { + int i = 4; + + SPFeFuncNode *funcNode = SP_FEFUNCNODE(node); + + switch (funcNode->channel) { + case SPFeFuncNode::R: + i = 0; + break; + case SPFeFuncNode::G: + i = 1; + break; + case SPFeFuncNode::B: + i = 2; + break; + case SPFeFuncNode::A: + i = 3; + break; + } + + if (i == 4) { g_warning("Unrecognized channel for component transfer."); break; } diff --git a/src/filters/distantlight.cpp b/src/filters/distantlight.cpp index 8b6ef023b..bd8bd2797 100644 --- a/src/filters/distantlight.cpp +++ b/src/filters/distantlight.cpp @@ -29,6 +29,18 @@ #define SP_MACROS_SILENT #include "macros.h" + +#include "sp-factory.h" + +namespace { + SPObject* createDistantLight() { + return new SPFeDistantLight(); + } + + bool distantLightRegistered = SPFactory::instance().registerObject("svg:feDistantLight", createDistantLight); +} + + SPFeDistantLight::SPFeDistantLight() : SPObject(), azimuth(0), azimuth_set(FALSE), elevation(0), elevation_set(FALSE) { } 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/gradient-drag.cpp b/src/gradient-drag.cpp index fb58aa508..b3622107b 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -1417,7 +1417,7 @@ void GrDragger::updateTip() if (g_slist_length (this->draggables) == 1) { GrDraggable *draggable = (GrDraggable *) this->draggables->data; - char *item_desc = draggable->item->getDetailedDescription(); + char *item_desc = draggable->item->detailedDescription(); switch (draggable->point_type) { case POINT_LG_MID: case POINT_RG_MID1: @@ -1438,7 +1438,7 @@ void GrDragger::updateTip() } g_free(item_desc); } else if (g_slist_length (draggables) == 2 && isA (POINT_RG_CENTER) && isA (POINT_RG_FOCUS)) { - this->knot->tip = g_strdup_printf (_("Radial gradient <b>center</b> and <b>focus</b>; drag with <b>Shift</b> to separate focus")); + this->knot->tip = g_strdup_printf ("%s", _("Radial gradient <b>center</b> and <b>focus</b>; drag with <b>Shift</b> to separate focus")); } else { int length = g_slist_length (this->draggables); this->knot->tip = g_strdup_printf (ngettext("Gradient point shared by <b>%d</b> gradient; drag with <b>Shift</b> to separate", 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/interface.cpp b/src/interface.cpp index ea5eaf16a..e57092e2b 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -50,6 +50,7 @@ #include "sp-gradient.h" #include "sp-flowtext.h" #include "sp-namedview.h" +#include "sp-root.h" #include "ui/view/view.h" #include "helper/action.h" #include "helper/action-context.h" @@ -321,6 +322,10 @@ sp_ui_close_view(GtkWidget */*widget*/) if (desktops.size() == 1) { Glib::ustring templateUri = sp_file_default_template_uri(); SPDocument *doc = SPDocument::createNewDoc( templateUri.c_str() , TRUE, true ); + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().quantity, doc->getHeight().quantity)); + } dt->change_document(doc); sp_namedview_window_from_document(dt); sp_namedview_update_layers_from_document(dt); @@ -716,33 +721,6 @@ sp_recent_open(GtkRecentChooser *recent_menu, gpointer /*user_data*/) g_free(uri); } -static bool -compare_file_basenames(gchar const *a, gchar const *b) { - bool rc; - gchar *ba, *bb; - - bool sort_by_fullname = true; // Sort by full name (including path) or just filename - if (sort_by_fullname) { - ba = g_strdup(a); - bb = g_strdup(b); - } else { - ba = g_path_get_basename(a); - bb = g_path_get_basename(b); - } - - gchar *fa = g_filename_to_utf8(ba, -1, NULL, NULL, NULL); - gchar *fb = g_filename_to_utf8(bb, -1, NULL, NULL, NULL); - g_free(ba); - g_free(bb); - - rc = g_utf8_collate(fa, fb) < 0; - - g_free(fa); - g_free(fb); - - return rc; -} - static void sp_ui_checkboxes_menus(GtkMenu *m, Inkscape::UI::View::View *view) { diff --git a/src/io/CMakeLists.txt b/src/io/CMakeLists.txt index 8f8355c03..ef577b014 100644 --- a/src/io/CMakeLists.txt +++ b/src/io/CMakeLists.txt @@ -2,7 +2,6 @@ set(io_SRC base64stream.cpp bufferstream.cpp - ftos.cpp gzipstream.cpp inkjar.cpp inkscapestream.cpp @@ -16,7 +15,6 @@ set(io_SRC # Headers base64stream.h bufferstream.h - ftos.h gzipstream.h inkjar.h inkscapestream.h diff --git a/src/libdepixelize/CMakeLists.txt b/src/libdepixelize/CMakeLists.txt index 64a72f9d9..895e16e85 100644 --- a/src/libdepixelize/CMakeLists.txt +++ b/src/libdepixelize/CMakeLists.txt @@ -4,8 +4,20 @@ set(libdepixelize_SRC # ------- # Headers - kopftracer2011.h - splines.h + kopftracer2011.h + splines.h + + priv/branchless.h + priv/colorspace.h + priv/curvature.h + priv/homogeneoussplines.h + priv/integral + priv/iterator.h + priv/optimization-kopf2011.h + priv/pixelgraph.h + priv/point.h + priv/simplifiedvoronoi.h + priv/splines-kopf2011.h ) add_inkscape_lib(depixelize_LIB "${libdepixelize_SRC}") diff --git a/src/libdepixelize/Makefile_insert b/src/libdepixelize/Makefile_insert index 75b19bf5c..b5be88c5f 100644 --- a/src/libdepixelize/Makefile_insert +++ b/src/libdepixelize/Makefile_insert @@ -5,7 +5,18 @@ libdepixelize/all: libdepixelize/libdepixelize.a libdepixelize/clean: rm -f libdepixelize/libdepixelize.a $(libdepixelize_libdepixelize_a_OBJECTS) -libdepixelize_libdepixelize_a_SOURCES = \ - libdepixelize/kopftracer2011.cpp \ - libdepixelize/kopftracer2011.h \ - libdepixelize/splines.h +libdepixelize_libdepixelize_a_SOURCES = \ + libdepixelize/kopftracer2011.cpp \ + libdepixelize/kopftracer2011.h \ + libdepixelize/splines.h \ + libdepixelize/priv/branchless.h \ + libdepixelize/priv/colorspace.h \ + libdepixelize/priv/curvature.h \ + libdepixelize/priv/homogeneoussplines.h \ + libdepixelize/priv/integral \ + libdepixelize/priv/iterator.h \ + libdepixelize/priv/optimization-kopf2011.h \ + libdepixelize/priv/pixelgraph.h \ + libdepixelize/priv/point.h \ + libdepixelize/priv/simplifiedvoronoi.h \ + libdepixelize/priv/splines-kopf2011.h diff --git a/src/libdepixelize/kopftracer2011.cpp b/src/libdepixelize/kopftracer2011.cpp index 26ad8863b..50b12d527 100644 --- a/src/libdepixelize/kopftracer2011.cpp +++ b/src/libdepixelize/kopftracer2011.cpp @@ -37,7 +37,7 @@ #include "priv/colorspace.h" #include "priv/homogeneoussplines.h" #include "priv/branchless.h" -#include "priv/splines.h" +#include "priv/splines-kopf2011.h" #include "priv/iterator.h" namespace Tracer { @@ -146,6 +146,12 @@ SimplifiedVoronoi<T> Kopf2011::_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &b graph.checkConsistency(); #endif + _remove_puzzle_pattern(graph); + +#ifndef NDEBUG + graph.checkConsistency(); +#endif + return SimplifiedVoronoi<T>(graph); } @@ -309,6 +315,33 @@ void Kopf2011::_remove_crossing_edges_unsafe(PixelGraph &graph, } } +inline +void Kopf2011::_remove_puzzle_pattern(PixelGraph &graph) +{ + if ( graph.width() < 2 || graph.height() < 2 ) + return; + + PixelGraph::iterator it = graph.begin(); + for ( int i = 0 ; i + 1 != graph.height() ; ++i ) { + PixelGraph::iterator it2 = it; + for ( int j = 0 ; j + 1 != graph.width() ; ++j ) { + // Evil pattern currently not handled correctly in SimplifiedVoronoi + if ( it2->adj.right + it2->adj.bottom + + graph.nodeBottomRight(it2)->adj.left + + graph.nodeBottomRight(it2)->adj.top == 3 ) { + // We fake a new connection =) + it2->adj.right = true; + it2->adj.bottom = true; + graph.nodeBottomRight(it2)->adj.left = true; + graph.nodeBottomRight(it2)->adj.top = true; + } + + it2 = graph.nodeRight(it2); + } + it = graph.nodeBottom(it); + } +} + inline int Heuristics::curves(const PixelGraph &graph, PixelGraph::const_iterator a, PixelGraph::const_iterator b) @@ -383,22 +416,25 @@ inline void Heuristics::SparsePixels::operator ()(const PixelGraph &graph, { unsigned x = graph.toX(diagonals[MAIN_DIAGONAL].first.first); unsigned y = graph.toY(diagonals[MAIN_DIAGONAL].first.first); - unsigned minor = std::min(x, y); unsigned displace = radius - 1; - if ( displace > minor ) { - displace = minor; - radius = displace + 1; + { + unsigned minor = std::min(x, y); + + if ( displace > minor ) { + displace = minor; + radius = displace + 1; + } } displace = radius; - if ( x + displace >= graph.width() ) { + if ( x + displace >= unsigned(graph.width()) ) { displace = unsigned(graph.width()) - x - 1; radius = displace; } - if ( y + displace >= graph.height() ) { + if ( y + displace >= unsigned(graph.height()) ) { displace = unsigned(graph.height()) - y - 1; radius = displace; } @@ -434,7 +470,6 @@ inline void Heuristics::SparsePixels::operator ()(const PixelGraph &graph, int minor = std::min(diagonals[0].second, diagonals[1].second); for ( int i = 0 ; i != 2 ; ++i ) diagonals[i].second -= minor; - std::swap(diagonals[0].second, diagonals[1].second); } diff --git a/src/libdepixelize/kopftracer2011.h b/src/libdepixelize/kopftracer2011.h index 73f3b7274..aff39d3d8 100644 --- a/src/libdepixelize/kopftracer2011.h +++ b/src/libdepixelize/kopftracer2011.h @@ -73,12 +73,17 @@ public: /** * # Exceptions * + * \p options.optimize and options.nthreads will be ignored + * * Glib::FileError * Gdk::PixbufError */ static Splines to_voronoi(const std::string &filename, const Options &options = Options()); + /* + * \p options.optimize and options.nthreads will be ignored + */ static Splines to_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf, const Options &options = Options()); @@ -95,7 +100,7 @@ public: const Options &options = Options()); private: - typedef double Precision; + typedef Geom::Coord Precision; template<class T> static SimplifiedVoronoi<T> _voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf, @@ -105,6 +110,7 @@ private: static void _remove_crossing_edges_safe(PixelGraph &graph); static void _remove_crossing_edges_unsafe(PixelGraph &graph, const Options &options); + static void _remove_puzzle_pattern(PixelGraph &graph); }; } // namespace Tracer diff --git a/src/libdepixelize/priv/curvature.h b/src/libdepixelize/priv/curvature.h new file mode 100644 index 000000000..3a1af4197 --- /dev/null +++ b/src/libdepixelize/priv/curvature.h @@ -0,0 +1,115 @@ +/* This file is part of the libdepixelize project + Copyright (C) 2013 VinÃcius dos Santos Oliveira <vini.ipsmaker@gmail.com> + + GNU Lesser General Public License Usage + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + You should have received a copy of the GNU Lesser General Public License + along with this library. If not, see <http://www.gnu.org/licenses/>. + + GNU General Public License Usage + Alternatively, this library may be used under the terms of the GNU General + Public License as published by the Free Software Foundation, either version + 2 of the License, or (at your option) any later version. + You should have received a copy of the GNU General Public License along with + this library. If not, see <http://www.gnu.org/licenses/>. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. +*/ + +#ifndef LIBDEPIXELIZE_TRACER_CURVATURE_H +#define LIBDEPIXELIZE_TRACER_CURVATURE_H + +#include "point.h" +#include <cmath> + +namespace Tracer { + +/** + * Curvature function for a quadratic Bézier curve where the points are know. + * Its main use is to numerically integrate the curvature function and then + * smooth the B-Splines generated by the Kopf-Lischinski algorithm. + */ +template<class T> +struct Curvature +{ + Curvature(Point<T> p0, Point<T> c1, Point<T> p2) : + p0(p0), c1(c1), p2(p2) + {} + + T operator()(T t) const; + + /** + * The derivative of x + */ + T xPrime(T t) const; + + /** + * The derivative of y + */ + T yPrime(T t) const; + + /** + * The second derivative of x + */ + T xPrimePrime() const; + + /** + * The second derivative of y + */ + T yPrimePrime() const; + + Point<T> p0, c1, p2; +}; + +template<class T> +T Curvature<T>::operator()(T t) const +{ + T num = xPrime(t) * yPrimePrime() - yPrime(t) * xPrimePrime(); + T den = std::pow(xPrime(t) * xPrime(t) + yPrime(t) * yPrime(t), T(3) / 2); + return num / den; +} + +template<class T> +T Curvature<T>::xPrime(T t) const +{ + return (1-t)*2*(c1.x-p0.x) + t*2*(p2.x-c1.x); +} + +template<class T> +T Curvature<T>::yPrime(T t) const +{ + return (1-t)*2*(c1.y-p0.y) + t*2*(p2.y-c1.y); +} + +template<class T> +T Curvature<T>::xPrimePrime() const +{ + return 2 * (p2.x - 2*c1.x + p0.x); +} + +template<class T> +T Curvature<T>::yPrimePrime() const +{ + return 2 * (p2.y - 2*c1.y + p0.y); +} + +} // namespace Tracer + +#endif // LIBDEPIXELIZE_TRACER_CURVATURE_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/libdepixelize/priv/integral.h b/src/libdepixelize/priv/integral.h new file mode 100644 index 000000000..fc1a49f27 --- /dev/null +++ b/src/libdepixelize/priv/integral.h @@ -0,0 +1,61 @@ +/* This file is part of the libdepixelize project + Copyright (C) 2013 VinÃcius dos Santos Oliveira <vini.ipsmaker@gmail.com> + + GNU Lesser General Public License Usage + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + You should have received a copy of the GNU Lesser General Public License + along with this library. If not, see <http://www.gnu.org/licenses/>. + + GNU General Public License Usage + Alternatively, this library may be used under the terms of the GNU General + Public License as published by the Free Software Foundation, either version + 2 of the License, or (at your option) any later version. + You should have received a copy of the GNU General Public License along with + this library. If not, see <http://www.gnu.org/licenses/>. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. +*/ + +#ifndef LIBDEPIXELIZE_TRACER_INTEGRAL_H +#define LIBDEPIXELIZE_TRACER_INTEGRAL_H + +#include <2geom/coord.h> + +namespace Tracer { + +/** + * Compute the integral numerically using Gaussian Quadrature rule with + * \p samples number of samples. + */ +template<class T, class F> +Geom::Coord integral(F f, T begin, T end, unsigned samples) +{ + T ret = 0; + const T width = (end - begin) / samples; + + for ( unsigned i = 0 ; i != samples ; ++i ) + ret += width * f(begin + width * (i + .5)); + + return ret; +} + +} // namespace Tracer + +#endif // LIBDEPIXELIZE_TRACER_INTEGRAL_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/libdepixelize/priv/optimization-kopf2011.h b/src/libdepixelize/priv/optimization-kopf2011.h new file mode 100644 index 000000000..0c9011ca7 --- /dev/null +++ b/src/libdepixelize/priv/optimization-kopf2011.h @@ -0,0 +1,263 @@ +/* This file is part of the libdepixelize project + Copyright (C) 2013 VinÃcius dos Santos Oliveira <vini.ipsmaker@gmail.com> + + GNU Lesser General Public License Usage + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + You should have received a copy of the GNU Lesser General Public License + along with this library. If not, see <http://www.gnu.org/licenses/>. + + GNU General Public License Usage + Alternatively, this library may be used under the terms of the GNU General + Public License as published by the Free Software Foundation, either version + 2 of the License, or (at your option) any later version. + You should have received a copy of the GNU General Public License along with + this library. If not, see <http://www.gnu.org/licenses/>. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. +*/ + +#ifndef LIBDEPIXELIZE_TRACER_OPTIMIZATION_KOPF2011_H +#define LIBDEPIXELIZE_TRACER_OPTIMIZATION_KOPF2011_H + +#include "curvature.h" +#include "integral.h" +#include <cmath> +#include <limits> + +namespace Tracer { + +/** + * m is angular coeficient + */ +template<class T> +bool is_valid_border_m(T a) +{ + if ( a < 0 ) + a *= -1; + + // TODO: alternative behaviour if has no infinity + return a == std::numeric_limits<T>::infinity() + || a == 3 || a == 1; +} + +/** + * Return true if the four points are considered a border. + */ +template<class T> +bool is_border(const Point<T> (&points)[4]) +{ + T dy[2]; + T dx[2]; + T m[2]; + if ( points[1].y == points[2].y ) { + dy[0] = points[1].y - points[0].y; + dy[1] = points[3].y - points[2].y; + + dx[0] = points[1].x - points[0].x; + dx[1] = points[3].x - points[2].x; + + m[0] = dy[0] / dx[0]; + m[1] = dy[1] / dx[1]; + } else if ( points[1].x == points[2].x ) { + // It's easier to have a unified logic, then we'll fake dx and dy + dy[0] = points[1].x - points[0].x; + dy[1] = points[3].x - points[2].x; + + dx[0] = points[1].y - points[0].y; + dx[1] = points[3].y - points[2].y; + + m[0] = dy[0] / dx[0]; + m[1] = dy[1] / dx[1]; + } else { + return false; + } + + return m[0] == -m[1] && is_valid_border_m(m[0]); +} + +template<class T> +typename std::vector< Point<T> >::iterator +skip1visible(typename std::vector< Point<T> >::iterator it, + typename std::vector< Point<T> >::iterator end) +{ + for ( ++it ; it != end ; ++it ) { + if ( it->visible ) + return it; + } + return end; +} + +/** + * Return how many elements should be skipped. + */ +template<class T> +typename std::vector< Point<T> >::difference_type +border_detection(typename std::vector< Point<T> >::iterator it, + typename std::vector< Point<T> >::iterator end) +{ + typename std::vector< Point<T> >::iterator begin = it; + + if ( end - it < 4 ) + return 0; + + Point<T> last[4]; + typename std::vector< Point<T> >::iterator prev = it; + + for ( int i = 0 ; i != 4 ; ++i ) { + if ( it == end ) + return 0; + last[i] = *it; + prev = it; + it = skip1visible<T>(it, end); + } + + if ( !is_border(last) ) + return 0; + + if ( it == end ) + return prev - begin; + + bool got_another = false; + for ( it = skip1visible<T>(it, end) ; it != end + ; it = skip1visible<T>(it, end) ) { + if ( !got_another ) { + last[0] = last[2]; + last[1] = last[3]; + last[2] = *it; + + got_another = true; + continue; + } + last[3] = *it; + + if ( !is_border(last) ) + return prev - begin; + prev = it; + } + + return prev - begin; +} + +template<class T> +T smoothness_energy(Point<T> c0, Point<T> c1, Point<T> c2) +{ + Point<T> p0 = midpoint(c0, c1); + Point<T> p2 = midpoint(c1, c2); + Curvature<T> cur(p0, c1, p2); + + return std::abs(integral<T>(cur, 0, 1, 16)); +} + +template<class T> +T positional_energy(Point<T> guess, Point<T> initial) +{ + using std::pow; + + return pow(pow(guess.x - initial.x, 2) + + pow(guess.y - initial.y, 2), 2); +} + +/** + * Kopf-Lischinski simple relaxation procedure: a random new offset position + * within a small radius around its current location. + * + * The small radius is not revealed. I chose the empirically determined value of + * 0.125. New tests can give a better value for "small". I believe this value + * showed up because the optimization sharply penalize larger deviations. + */ +template<class T> +Point<T> optimization_guess(Point<T> p) +{ + // See the value explanation in the function documentation. + T radius = 0.125; + + T d[] = { + (T(std::rand()) / RAND_MAX) * radius * 2 - radius, + (T(std::rand()) / RAND_MAX) * radius * 2 - radius + }; + + return p + Point<T>(d[0], d[1]); +} + +template<class T> +std::vector< Point<T> > optimize(const std::vector< Point<T> > &path) +{ + typedef std::vector< Point<T> > Path; + + Path ret = path; + + /* The number of vertices not constrained by optimization */ + unsigned n = 0; + + /* Values chosen by test + * TODO: make values configurable via function parameters. */ + const unsigned iterations = 4; + const unsigned nguess_per_iteration = 4; + + for ( unsigned i = 0 ; i != iterations ; ++i ) { + n = 0; + + /* This iteration bounds is not something to worry about, because the + * smallest path has size 4. */ + for ( typename Path::size_type j = 0 ; j != ret.size() ; ++j ) { + Point<T> prev = ( j == 0 ) ? ret.back() : ret[j-1]; + Point<T> next = ( j + 1 == ret.size() ) ? ret.front() : ret[j+1] ; + + if ( !ret[j].visible || !ret[j].smooth ) + continue; + + { + typename Path::iterator it = ret.begin() + j; + typename Path::difference_type skip + = border_detection<T>(it, ret.end()); + j += skip; + if ( j == ret.size() ) + break; + } + + ++n; + + for ( unsigned k = 0 ; k != nguess_per_iteration ; ++k ) { + Point<T> guess = optimization_guess(ret[j]); + + T s = smoothness_energy(prev, guess, next); + T p = positional_energy(guess, path[j]); + + T e = s + p; + + T prev_e = smoothness_energy(prev, ret[j], next) + + positional_energy(ret[j], path[j]); + + if ( prev_e > e ) { + // We don't want to screw other metadata, then we manually + // assign the new coords + ret[j].x = guess.x; + ret[j].y = guess.y; + } + } + } + } + + return ret; +} + +} // namespace Tracer + +#endif // LIBDEPIXELIZE_TRACER_OPTIMIZATION_KOPF2011_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/libdepixelize/priv/pixelgraph.h b/src/libdepixelize/priv/pixelgraph.h index 32523d8ee..9e8c2124a 100644 --- a/src/libdepixelize/priv/pixelgraph.h +++ b/src/libdepixelize/priv/pixelgraph.h @@ -378,7 +378,7 @@ inline void PixelGraph::connectAllNeighbors() it = nodeRight(it); } - // After the previous loop, 'it' is poiting to the last node from + // After the previous loop, 'it' is pointing to the last node from // the row. // Go south, then first node in the row (increment 'it' by 1) // Go to the second node in the line (increment 'it' by 1) @@ -445,21 +445,34 @@ inline void PixelGraph::connectAllNeighbors() // ...and the 4 corner nodes { Node *const top_left = &(*this)[0][0]; - top_left->adj.right = 1; - top_left->adj.bottomright = 1; - top_left->adj.bottom = 1; + + if ( _width > 1 ) + top_left->adj.right = 1; + + if ( _width > 1 && _height > 1 ) + top_left->adj.bottomright = 1; + + if ( _height > 1 ) + top_left->adj.bottom = 1; } if ( _width > 1 ) { Node *const top_right = &(*this)[_width - 1][0]; - top_right->adj.bottom = 1; - top_right->adj.bottomleft = 1; + + if ( _height > 1 ) { + top_right->adj.bottom = 1; + top_right->adj.bottomleft = 1; + } + top_right->adj.left = 1; } if ( _height > 1 ) { Node *const down_left = &(*this)[0][_height - 1]; down_left->adj.top = 1; - down_left->adj.topright = 1; - down_left->adj.right = 1; + + if ( _width > 1 ) { + down_left->adj.topright = 1; + down_left->adj.right = 1; + } } if ( _width > 1 && _height > 1 ) { Node *const down_right = &(*this)[_width - 1][_height - 1]; diff --git a/src/libdepixelize/priv/point.h b/src/libdepixelize/priv/point.h index 6bea752ed..dc28a2b84 100644 --- a/src/libdepixelize/priv/point.h +++ b/src/libdepixelize/priv/point.h @@ -30,9 +30,9 @@ namespace Tracer { template<class T> struct Point { - Point() {} - Point(T x, T y) : x(x), y(y) {} - Point(T x, T y, bool smooth) : smooth(smooth), x(x), y(y) {} + Point() : visible(true) {} + Point(T x, T y) : visible(true), x(x), y(y) {} + Point(T x, T y, bool smooth) : smooth(smooth), visible(true), x(x), y(y) {} Point operator+(const Point &rhs) const { @@ -44,21 +44,58 @@ struct Point return Point(x / foo, y / foo); } + Point invisible() const + { + Point p = *this; + p.visible = false; + return p; + } + bool smooth; + /** + * By default, all points are visible, but the poor amount of information + * that B-Splines (libdepixelize-specific) allows us to represent forces us + * to create additional points. But... these additional points don't need to + * be visible. + */ + bool visible; + T x, y; }; template<class T> -inline bool operator==(const Point<T> &lhs, const Point<T> &rhs) +Point<T> midpoint(const Point<T> &a, const Point<T> &b) +{ + return Point<T>((a.x + b.x) / 2, (a.y + b.y) / 2); +} + +template<class T> +bool operator==(const Point<T> &lhs, const Point<T> &rhs) { return + /* + * Will make a better job identifying which points can be eliminated by + * cells union. + */ #ifndef LIBDEPIXELIZE_IS_VERY_WELL_TESTED lhs.smooth == rhs.smooth && #endif // LIBDEPIXELIZE_IS_VERY_WELL_TESTED lhs.x == rhs.x && lhs.y == rhs.y; } +template<class T> +bool weakly_equal(const Point<T> &a, const Point<T> &b) +{ + return a.x == b.x && a.y == b.y; +} + +template<class T> +Geom::Point to_geom_point(Point<T> p) +{ + return Geom::Point(p.x, p.y); +} + } // namespace Tracer #endif // LIBDEPIXELIZE_TRACER_POINT_H diff --git a/src/libdepixelize/priv/simplifiedvoronoi.h b/src/libdepixelize/priv/simplifiedvoronoi.h index a33695ff7..d5ebc36e5 100644 --- a/src/libdepixelize/priv/simplifiedvoronoi.h +++ b/src/libdepixelize/priv/simplifiedvoronoi.h @@ -124,11 +124,6 @@ private: typedef void (*PointTransform)(Point<T> &p, T dx, T dy); typedef bool (*NodeTransform)(PixelGraph::const_iterator); - static Point<T> _midpoint(const Point<T> &p1, const Point<T> p2) - { - return Point<T>((p1.x + p2.x) / 2, (p1.y + p2.y) / 2); - } - /** * Output is translated by -.5 in each axis. This function fixes this error. */ @@ -220,7 +215,7 @@ private: * code base 4 times smaller and bugs will be MUCH MUCH difficult to hide. * * Some maintainers may go mad because the level extra level of - * abstracation. + * abstraction. * * "All problems in computer science can be solved by another level of * indirection, except for the problem of too many layers of indirection." @@ -255,6 +250,11 @@ SimplifiedVoronoi<T>::SimplifiedVoronoi(const PixelGraph &graph) : if (!graph.size()) return; + /* + * The insertion order of cells is not a big deal. Here I just follow + * the order of PixelGraph arrangement. + */ + // ...the "center" cells first... if ( _width > 2 && _height > 2 ) { PixelGraph::const_iterator graph_it = graph.begin() + _width + 1; @@ -276,7 +276,7 @@ SimplifiedVoronoi<T>::SimplifiedVoronoi(const PixelGraph &graph) : // Bottom-left _complexBottomLeft(graph, graph_it, cells_it, j, i); } - // After the previous loop, 'it' is poiting to the last cell from + // After the previous loop, 'it' is pointing to the last cell from // the row. // Go south, then first node in the row (increment 'it' by 1) // Go to the second node in the line (increment 'it' by 1) @@ -794,13 +794,13 @@ SimplifiedVoronoi<T> PixelGraph::const_iterator d_it, Cell *const cells_it, int x, int y, PointTransform transform, - NodeTransform top, + NodeTransform, NodeTransform topright, NodeTransform right, NodeTransform bottomright, NodeTransform bottom, NodeTransform bottomleft, - NodeTransform left, + NodeTransform, NodeTransform topleft) { using colorspace::contour_edge; @@ -808,31 +808,36 @@ SimplifiedVoronoi<T> const Point<T> initial(x, y); + /* + * The insertion order of points within the cell is very important. You must + * follow current practice: Clockwise order. + */ + if ( bottomright(a_it) ) { // this and bottom-right are connected bool smooth[2] = { - same_color(a_it->rgba, d_it->rgba) + right(a_it), - same_color(a_it->rgba, d_it->rgba) + bottom(a_it) + same_color(a_it->rgba, d_it->rgba) || right(a_it), + same_color(a_it->rgba, d_it->rgba) || bottom(a_it) }; Point<T> borderMid = initial; { transform(borderMid, 1, 1); - borderMid = _midpoint(initial, borderMid); + borderMid = midpoint(initial, borderMid); } Point<T> vertices[2] = {initial, initial}; { transform(vertices[0], 1, 0); - vertices[0] = _adjust(_midpoint(borderMid, vertices[0]), smooth[0]); + vertices[0] = _adjust(midpoint(borderMid, vertices[0]), smooth[0]); transform(vertices[1], 0, 1); - vertices[1] = _adjust(_midpoint(borderMid, vertices[1]), smooth[1]); + vertices[1] = _adjust(midpoint(borderMid, vertices[1]), smooth[1]); } if ( !smooth[0] ) { - cells_it->vertices.push_back(vertices[0]); + cells_it->vertices.push_back(vertices[0].invisible()); { Point<T> another = vertices[0]; transform(another, @@ -841,7 +846,7 @@ SimplifiedVoronoi<T> // y - ( 0.5625 - ( topright(a_it) + topleft(b_it) ) * 0.1875 )); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertices[0]; @@ -862,7 +867,7 @@ SimplifiedVoronoi<T> // y 0.0625 + ( bottomright(b_it) - topright(d_it) ) * 0.0625); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { transform(vertices[0], @@ -874,6 +879,7 @@ SimplifiedVoronoi<T> + ( topright(d_it) - topright(a_it) - topleft(b_it) - bottomright(b_it) ) * 0.03125 )); + vertices[0].visible = false; } } @@ -891,7 +897,7 @@ SimplifiedVoronoi<T> 0.0625 + ( bottomleft(a_it) - bottomleft(d_it) - topleft(c_it) - bottomright(c_it) ) * 0.03125); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertices[1]; @@ -901,7 +907,7 @@ SimplifiedVoronoi<T> // y 0.1875 - ( bottomright(c_it) + bottomleft(d_it) ) * 0.0625); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertices[1]; @@ -926,8 +932,9 @@ SimplifiedVoronoi<T> - ( 0.1875 - ( bottomleft(a_it) - topleft(c_it) ) * 0.1875 )); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } + vertices[1].visible = false; } cells_it->vertices.push_back(vertices[1]); @@ -936,7 +943,7 @@ SimplifiedVoronoi<T> Point<T> vertex = initial; transform(vertex, 1, 1); - vertex = _adjust(_midpoint(_midpoint(initial, vertex), initial), true); + vertex = _adjust(midpoint(midpoint(initial, vertex), initial), true); cells_it->vertices.push_back(vertex); } else { // Connections don't affect the shape of this squared-like @@ -944,7 +951,7 @@ SimplifiedVoronoi<T> Point<T> vertex = initial; transform(vertex, 1, 1); - vertex = _adjust(_midpoint(initial, vertex)); + vertex = _adjust(midpoint(initial, vertex)); // compute smoothness if ( right(a_it) ) { @@ -969,13 +976,13 @@ SimplifiedVoronoi<T> - ( ( bottomright(c_it) + topleft(c_it) ) * 0.03125 ); transform(another, - amount, amount); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertex; T amount = 0.0625 * bottomright(c_it); transform(another, amount, 0.25 - amount); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertex; @@ -990,8 +997,9 @@ SimplifiedVoronoi<T> T amount = 0.1875 * topleft(c_it); transform(another, - ( 0.75 - amount ), - amount); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } + vertex.visible = false; } else if ( twin_is_contour ) { T amount = 0.125 - ( ( bottomleft(d_it) + topright(d_it) ) @@ -1036,13 +1044,13 @@ SimplifiedVoronoi<T> if ( !vertex.smooth ) { if ( another_is_contour ) { - cells_it->vertices.push_back(vertex); + cells_it->vertices.push_back(vertex.invisible()); { Point<T> another = vertex; T amount = 0.1875 * topleft(b_it); transform(another, - amount, - ( 0.75 - amount )); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertex; @@ -1056,13 +1064,14 @@ SimplifiedVoronoi<T> Point<T> another = vertex; T amount = 0.0625 * bottomright(b_it); transform(another, 0.25 - amount, amount); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { T amount = 0.125 - (bottomright(b_it) + topleft(b_it)) * 0.03125; transform(vertex, amount, - amount); + vertex.visible = false; } } else if ( twin_is_contour ) { T amount = 0.125 @@ -1115,13 +1124,13 @@ SimplifiedVoronoi<T> - ( topleft(c_it) + bottomright(c_it) ) * 0.03125; transform(another, - amount, amount); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertex; T amount = 0.0625 * bottomright(c_it); transform(another, amount, 0.25 - amount); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertex; @@ -1134,8 +1143,9 @@ SimplifiedVoronoi<T> Point<T> another = vertex; T amount = 0.1875 * topleft(c_it); transform(another, - ( 0.75 - amount ), - amount); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } + vertex.visible = false; } else { special = true; } @@ -1149,7 +1159,7 @@ SimplifiedVoronoi<T> } if ( special ) { - cells_it->vertices.push_back(vertex); + cells_it->vertices.push_back(vertex.invisible()); { Point<T> another = vertex; T amount = 0.1875; @@ -1159,7 +1169,7 @@ SimplifiedVoronoi<T> - ( 0.75 - ( topleft(b_it) + topright(a_it) ) * amount )); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertex; @@ -1181,7 +1191,7 @@ SimplifiedVoronoi<T> // y 0.25 - amount * ( bottomleft(d_it) + bottomright(c_it) )); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { transform(vertex, @@ -1192,6 +1202,7 @@ SimplifiedVoronoi<T> ( topleft(b_it) - bottomleft(d_it) + topright(a_it) - bottomright(c_it) ) * 0.03125); + vertex.visible = false; } } } else if ( right(c_it) ) { @@ -1212,12 +1223,12 @@ SimplifiedVoronoi<T> if ( !vertex.smooth ) { if ( similar_neighbor_is_contour ) { - cells_it->vertices.push_back(vertex); + cells_it->vertices.push_back(vertex.invisible()); { Point<T> another = vertex; T amount = 0.1875 * topleft(b_it); transform(another, - amount, - ( 0.75 - amount )); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertex; @@ -1230,12 +1241,13 @@ SimplifiedVoronoi<T> Point<T> another = vertex; T amount = 0.0625 * bottomright(b_it); transform(another, 0.25 - amount, amount); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { T amount = 0.125 - 0.03125 * (topleft(b_it) + bottomright(b_it)); transform(vertex, amount, - amount); + vertex.visible = false; } } else { special = true; @@ -1261,7 +1273,7 @@ SimplifiedVoronoi<T> - amount * ( topleft(c_it) + topright(d_it) - bottomleft(a_it) - bottomright(b_it) )); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertex; @@ -1272,7 +1284,7 @@ SimplifiedVoronoi<T> // y - amount * ( topright(d_it) - bottomright(b_it) )); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } { Point<T> another = vertex; @@ -1295,8 +1307,9 @@ SimplifiedVoronoi<T> // y - amount * ( topleft(c_it) - bottomleft(a_it) )); - cells_it->vertices.push_back(another); + cells_it->vertices.push_back(another.invisible()); } + vertex.visible = false; } } else { // there is a 4-color pattern, where the current node diff --git a/src/libdepixelize/priv/splines.h b/src/libdepixelize/priv/splines-kopf2011.h index c7ef2b492..eb84c3bfb 100644 --- a/src/libdepixelize/priv/splines.h +++ b/src/libdepixelize/priv/splines-kopf2011.h @@ -22,55 +22,65 @@ Lesser General Public License for more details. */ -#ifndef LIBDEPIXELIZE_TRACER_SPLINES_PRIV_H -#define LIBDEPIXELIZE_TRACER_SPLINES_PRIV_H +#ifndef LIBDEPIXELIZE_TRACER_SPLINES_KOPF2011_H +#define LIBDEPIXELIZE_TRACER_SPLINES_KOPF2011_H #include "../splines.h" #include "homogeneoussplines.h" +#include "optimization-kopf2011.h" namespace Tracer { +/** + * Maybe the pass-by-value and then move idiom should be more efficient. But all + * this is inlinable and we're not even in C++11 yet. + */ template<class T> -Geom::Point to_geom_point(Point<T> p) -{ - return Geom::Point(p.x, p.y); -} - -template<class T> -Geom::Path worker_helper(const std::vector< Point<T> > &source, bool optimize) +Geom::Path worker_helper(const std::vector< Point<T> > &source1, bool optimize) { typedef Geom::LineSegment Line; typedef Geom::QuadraticBezier Quad; typedef typename std::vector< Point<T> >::const_iterator iterator; - iterator it = source.begin(); - Geom::Path ret(to_geom_point((source.back() + *it) / 2)); + std::vector< Point<T> > source; - for ( iterator end = --source.end() ; it != end ; ++it ) { - Point<T> next = *(it + 1); - Point<T> middle = (*it + next) / 2; + if ( optimize ) + source = Tracer::optimize(source1); + else + source = source1; - if ( !it->smooth ) { - // TODO: remove redundant colinear points - ret.appendNew<Line>(Geom::Point(it->x, it->y)); - ret.appendNew<Line>(Geom::Point(middle.x, middle.y)); - } else { - ret.appendNew<Quad>(Geom::Point(it->x, it->y), - Geom::Point(middle.x, middle.y)); + iterator it = source.begin(); + Point<T> prev = source.back(); + Geom::Path ret(to_geom_point(midpoint(prev, *it))); + + for ( iterator end = source.end() ; it != end ; ++it ) { +#if LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES + // remove redundant points + if ( !it->visible ) { + prev = *it; + continue; + } +#endif // LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES + + if ( !prev.visible ) { + Geom::Point middle = to_geom_point(midpoint(prev, *it)); + if ( ret.finalPoint() != middle ) { + // All generated invisible points are straight lines + ret.appendNew<Line>(middle); + } } - } - { - Point<T> next = source.front(); - Point<T> middle = (*it + next) / 2; + Point<T> next = (it + 1 == end) ? source.front() : *(it + 1); + Point<T> middle = midpoint(*it, next); if ( !it->smooth ) { - ret.appendNew<Line>(Geom::Point(it->x, it->y)); - ret.appendNew<Line>(Geom::Point(middle.x, middle.y)); + ret.appendNew<Line>(to_geom_point(*it)); + ret.appendNew<Line>(to_geom_point(middle)); } else { - ret.appendNew<Quad>(Geom::Point(it->x, it->y), - Geom::Point(middle.x, middle.y)); + ret.appendNew<Quad>(to_geom_point(*it), to_geom_point(middle)); } + + prev = *it; } return ret; @@ -98,7 +108,9 @@ void worker(const typename HomogeneousSplines<T>::Polygon &source, } template<typename T> -Splines::Splines(const SimplifiedVoronoi<T> &diagram) +Splines::Splines(const SimplifiedVoronoi<T> &diagram) : + _width(diagram.width()), + _height(diagram.height()) { _paths.reserve(diagram.size()); @@ -141,7 +153,7 @@ Splines::Splines(const HomogeneousSplines<T> &homogeneousSplines, } // namespace Tracer -#endif // LIBDEPIXELIZE_TRACER_SPLINES_PRIV_H +#endif // LIBDEPIXELIZE_TRACER_SPLINES_KOPF2011_H /* Local Variables: diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 74c706a1b..c91e57065 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -962,7 +962,7 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) nFace = pango_font_map_load_font(fontServer,fontContext,descr); } else { - g_warning(_("Ignoring font without family that will crash Pango")); + g_warning("%s", _("Ignoring font without family that will crash Pango")); } if ( nFace ) { diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index f7f910c2f..060cecebf 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -181,8 +181,9 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const glyph_index++; } nr_text->setStyle(text_source->style); - nr_text->setItemBounds(paintbox); in_arena->prependChild(nr_text); + // Set item bounds without filter enlargement + in_arena->setItemBounds(paintbox); } } 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..1c0f4cee7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,7 +11,7 @@ * Michael Meeks <michael@helixcode.com> * Chema Celorio <chema@celorio.com> * Pawel Palucha - * Bryce Harrington <bryce@bryceharrington.com> + * Bryce Harrington <bryce@bryceharrington.org> * ... and various people who have worked with various projects * Jon A. Cruz <jon@oncruz.org> * Abhishek Sharma @@ -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/marker.cpp b/src/marker.cpp index 730985b01..45188b4a4 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -35,11 +35,6 @@ struct SPMarkerView { std::vector<Inkscape::DrawingItem *> items; }; -static Inkscape::DrawingItem *sp_marker_private_show (SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); -static void sp_marker_private_hide (SPItem *item, unsigned int key); -static Geom::OptRect sp_marker_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type); -static void sp_marker_print (SPItem *item, SPPrintContext *ctx); - static void sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems); #include "sp-factory.h" @@ -503,57 +498,19 @@ Inkscape::DrawingItem* SPMarker::show(Inkscape::Drawing &drawing, unsigned int k return SPGroup::show(drawing, key, flags); } -/** - * This routine is disabled to break propagation. - */ -static Inkscape::DrawingItem * -sp_marker_private_show (SPItem */*item*/, Inkscape::Drawing &/*drawing*/, unsigned int /*key*/, unsigned int /*flags*/) -{ - /* Break propagation */ - return NULL; -} - void SPMarker::hide(unsigned int key) { // CPPIFY: correct? SPGroup::hide(key); } -/** - * This routine is disabled to break propagation. - */ -static void -sp_marker_private_hide (SPItem */*item*/, unsigned int /*key*/) -{ - /* Break propagation */ -} - Geom::OptRect SPMarker::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { return Geom::OptRect(); } -/** - * This routine is disabled to break propagation. - */ -static Geom::OptRect -sp_marker_bbox(SPItem const *, Geom::Affine const &, SPItem::BBoxType) -{ - /* Break propagation */ - return Geom::OptRect(); -} - void SPMarker::print(SPPrintContext* ctx) { } -/** - * This routine is disabled to break propagation. - */ -static void -sp_marker_print (SPItem */*item*/, SPPrintContext */*ctx*/) -{ - /* Break propagation */ -} - /* fixme: Remove link if zero-sized (Lauris) */ /** 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..f60b3d465 100644 --- a/src/rect-context.cpp +++ b/src/rect-context.cpp @@ -165,9 +165,7 @@ bool SPRectContext::item_handler(SPItem* item, GdkEvent* event) { break; } - if (!ret) { - ret = SPEventContext::item_handler(item, event); - } + ret = SPEventContext::item_handler(item, event); return ret; } @@ -478,6 +476,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.h b/src/selection-chemistry.h index f7a4f928c..e86000f70 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -85,7 +85,7 @@ void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *deskto void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop); void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop); -SPCSSAttr *take_style_from_item (SPItem *item); +SPCSSAttr *take_style_from_item (SPObject *object); void sp_selection_cut(SPDesktop *desktop); void sp_selection_copy(SPDesktop *desktop); diff --git a/src/selection-describer.cpp b/src/selection-describer.cpp index 4c2229667..5dddb0832 100644 --- a/src/selection-describer.cpp +++ b/src/selection-describer.cpp @@ -38,64 +38,22 @@ #include "sp-polyline.h" #include "sp-spiral.h" -// CPPIFY: this is ugly. -static const gchar * -type2term(SPItem *item) +// Returns a list of terms for the items to be used in the statusbar +char* collect_terms (GSList *items) { -// GType type = G_OBJECT_TYPE( item ); -// if (type == SP_TYPE_ANCHOR) -// //TRANSLATORS: "Link" means internet link (anchor) -// { return C_("Web", "Link"); } -// if (type == SP_TYPE_CIRCLE) -// { return _("Circle"); } -// if (type == SP_TYPE_ELLIPSE) -// { return _("Ellipse"); } -// if (type == SP_TYPE_FLOWTEXT) -// { return _("Flowed text"); } -// if (type == SP_TYPE_GROUP) -// { return _("Group"); } -// if (type == SP_TYPE_IMAGE) -// { return _("Image"); } -// if (type == SP_TYPE_LINE) -// { return _("Line"); } -// if (type == SP_TYPE_PATH) -// { return _("Path"); } -// if (type == SP_TYPE_POLYGON) -// { return _("Polygon"); } -// if (type == SP_TYPE_POLYLINE) -// { return _("Polyline"); } -// if (type == SP_TYPE_RECT) -// { return _("Rectangle"); } -// if (type == SP_TYPE_BOX3D) -// { return _("3D Box"); } -// if (type == SP_TYPE_TEXT) -// { return C_("Object", "Text"); } -// if (type == SP_TYPE_USE) -// if (SP_IS_SYMBOL(item->firstChild())) -// { return C_("Object", "Symbol"); } -// // TRANSLATORS: "Clone" is a noun, type of object -// { return C_("Object", "Clone"); } -// if (type == SP_TYPE_ARC) -// { return _("Ellipse"); } -// if (type == SP_TYPE_OFFSET) -// { return _("Offset path"); } -// if (type == SP_TYPE_SPIRAL) -// { return _("Spiral"); } -// if (type == SP_TYPE_STAR) -// { return _("Star"); } -// return NULL; - return "Selektion-Describer ---"; -} - -static GSList *collect_terms (GSList *items) -{ - GSList *r = NULL; - for (GSList *i = items; i != NULL; i = i->next) { - const gchar *term = type2term ( SP_ITEM(i->data) ); - if (term != NULL && g_slist_find (r, term) == NULL) - r = g_slist_prepend (r, (void *) term); + GSList *check = NULL; + std::stringstream ss; + bool first = true; + + for (GSList *i = (GSList *)items; i != NULL; i = i->next) { + const char *term = SP_ITEM(i->data)->displayName(); + if (term != NULL && g_slist_find (check, term) == NULL) { + check = g_slist_prepend (check, (void *) term); + ss << (first ? "" : ", ") << "<b>" << term << "</b>"; + first = false; + } } - return r; + return g_strdup(ss.str().c_str()); } // Returns the number of filtered items in the list @@ -188,20 +146,21 @@ void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *select if (layer == parent) in_phrase = g_strdup_printf(_(" in %s"), layer_name); else if (!layer) - in_phrase = g_strdup_printf(_(" hidden in definitions")); + in_phrase = g_strdup_printf("%s", _(" hidden in definitions")); else in_phrase = g_strdup_printf(_(" in group %s (%s)"), parent_name, layer_name); } else { - in_phrase = g_strdup_printf(ngettext(" in <b>%i</b> parents (%s)", " in <b>%i</b> parents (%s)", num_parents), num_parents, layer_name); + in_phrase = g_strdup_printf(ngettext(" in <b>%i</b> parent (%s)", " in <b>%i</b> parents (%s)", num_parents), num_parents, layer_name); } } else { - in_phrase = g_strdup_printf(ngettext(" in <b>%i</b> layers", " in <b>%i</b> layers", num_layers), num_layers); + in_phrase = g_strdup_printf(ngettext(" in <b>%i</b> layer", " in <b>%i</b> layers", num_layers), num_layers); } g_free (layer_name); g_free (parent_name); if (!items->next) { // one item - char *item_desc = item->description(); + char *item_desc = item->detailedDescription(); + if (SP_IS_USE(item) && SP_IS_SYMBOL(item->firstChild())) { _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", item_desc, in_phrase, @@ -228,39 +187,13 @@ void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *select } g_free(item_desc); } else { // multiple items - int object_count = g_slist_length((GSList *)items); + int objcount = g_slist_length((GSList *)items); + char *terms = collect_terms ((GSList *)items); - gchar *objects_str = NULL; - GSList *terms = collect_terms ((GSList *)items); - int n_terms = g_slist_length(terms); - if (n_terms == 0) { - objects_str = g_strdup_printf ( - // this is only used with 2 or more objects - ngettext("<b>%i</b> object selected", "<b>%i</b> objects selected", object_count), - object_count); - } else if (n_terms == 1) { - objects_str = g_strdup_printf ( - // this is only used with 2 or more objects - ngettext("<b>%i</b> object of type <b>%s</b>", "<b>%i</b> objects of type <b>%s</b>", object_count), - object_count, (gchar *) terms->data); - } else if (n_terms == 2) { - objects_str = g_strdup_printf ( - // this is only used with 2 or more objects - ngettext("<b>%i</b> object of types <b>%s</b>, <b>%s</b>", "<b>%i</b> objects of types <b>%s</b>, <b>%s</b>", object_count), - object_count, (gchar *) terms->data, (gchar *) terms->next->data); - } else if (n_terms == 3) { - objects_str = g_strdup_printf ( - // this is only used with 2 or more objects - ngettext("<b>%i</b> object of types <b>%s</b>, <b>%s</b>, <b>%s</b>", "<b>%i</b> objects of types <b>%s</b>, <b>%s</b>, <b>%s</b>", object_count), - object_count, (gchar *) terms->data, (gchar *) terms->next->data, (gchar *) terms->next->next->data); - } else { - objects_str = g_strdup_printf ( - // this is only used with 2 or more objects - ngettext("<b>%i</b> object of <b>%i</b> types", "<b>%i</b> objects of <b>%i</b> types", object_count), - object_count, n_terms); - } - g_slist_free (terms); + gchar *objects_str = g_strdup_printf( + "<b>%i</b> objects selected of types %s", objcount, terms); + g_free(terms); // indicate all, some, or none filtered gchar *filt_str = NULL; @@ -269,7 +202,7 @@ void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *select filt_str = g_strdup_printf(ngettext("; <i>%d filtered object</i> ", "; <i>%d filtered objects</i> ", n_filt), n_filt); } else { - filt_str = g_strdup_printf("%s", ""); + filt_str = g_strdup(""); } _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s%s. %s.", objects_str, filt_str, in_phrase, _when_selected); @@ -279,7 +212,7 @@ void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *select } if (filt_str) { g_free(filt_str); - objects_str = 0; + filt_str = 0; } } diff --git a/src/selection.cpp b/src/selection.cpp index 1335c5fca..aea5f539c 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -238,14 +238,7 @@ void Selection::_remove(SPObject *obj) { void Selection::setList(GSList const *list) { _clear(); - - if ( list != NULL ) { - for ( GSList const *iter = list ; iter != NULL ; iter = iter->next ) { - _add(reinterpret_cast<SPObject *>(iter->data)); - } - } - - _emitChanged(); + addList(list); } void Selection::addList(GSList const *list) { @@ -257,9 +250,7 @@ void Selection::addList(GSList const *list) { for ( GSList const *iter = list ; iter != NULL ; iter = iter->next ) { SPObject *obj = reinterpret_cast<SPObject *>(iter->data); - if (includes(obj)) { - continue; - } + if (includes(obj)) continue; _add (obj); } 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-anchor.cpp b/src/sp-anchor.cpp index d9a8c4142..a6a41bef3 100644 --- a/src/sp-anchor.cpp +++ b/src/sp-anchor.cpp @@ -115,14 +115,18 @@ Inkscape::XML::Node* SPAnchor::write(Inkscape::XML::Document *xml_doc, Inkscape: return repr; } +const char* SPAnchor::displayName() { + return _("Link"); +} + gchar* SPAnchor::description() { if (this->href) { char *quoted_href = xml_quote_strdup(this->href); - char *ret = g_strdup_printf(_("<b>Link</b> to %s"), quoted_href); + char *ret = g_strdup_printf(_("to %s"), quoted_href); g_free(quoted_href); return ret; } else { - return g_strdup (_("<b>Link</b> without URI")); + return g_strdup (_("without URI")); } } diff --git a/src/sp-anchor.h b/src/sp-anchor.h index cada9665e..39f6d0b7a 100644 --- a/src/sp-anchor.h +++ b/src/sp-anchor.h @@ -30,6 +30,7 @@ public: virtual void set(unsigned int key, gchar const* value); virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual const char* displayName(); virtual gchar* description(); virtual gint event(SPEvent *event); }; diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index a3e1a475a..09b99dad1 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -322,6 +322,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) { @@ -431,8 +484,8 @@ void SPEllipse::set(unsigned int key, gchar const* value) { } } -gchar* SPEllipse::description() { - return g_strdup(_("<b>Ellipse</b>")); +const char* SPEllipse::displayName() { + return _("Ellipse"); } @@ -511,8 +564,8 @@ void SPCircle::set(unsigned int key, gchar const* value) { } } -gchar* SPCircle::description() { - return g_strdup(_("<b>Circle</b>")); +const char* SPCircle::displayName() { + return _("Circle"); } /* <path sodipodi:type="arc"> element */ @@ -685,7 +738,7 @@ void SPArc::modified(guint flags) { } -gchar* SPArc::description() { +const char* SPArc::displayName() { gdouble len = fmod(this->end - this->start, SP_2PI); if (len < 0.0) { @@ -694,12 +747,12 @@ gchar* SPArc::description() { if (!(fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8)) { if (this->closed) { - return g_strdup(_("<b>Segment</b>")); + return _("Segment"); } else { - return g_strdup(_("<b>Arc</b>")); + return _("Arc"); } } else { - return g_strdup(_("<b>Ellipse</b>")); + return _("Ellipse"); } } diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h index 67e12006a..083f5847d 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); }; @@ -58,7 +59,7 @@ public: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); virtual void set(unsigned int key, gchar const* value); - virtual gchar* description(); + virtual const char* displayName(); }; void sp_ellipse_position_set (SPEllipse * ellipse, gdouble x, gdouble y, gdouble rx, gdouble ry); @@ -75,7 +76,7 @@ public: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); virtual void set(unsigned int key, gchar const* value); - virtual gchar* description(); + virtual const char* displayName(); }; /* <path sodipodi:type="arc"> element */ @@ -90,7 +91,7 @@ public: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); virtual void set(unsigned int key, gchar const* value); - virtual gchar* description(); + virtual const char* displayName(); virtual void modified(unsigned int flags); }; diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index 3a0aef6be..ed17f1948 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -188,14 +188,11 @@ Inkscape::XML::Node *SPFlowregion::write(Inkscape::XML::Document *xml_doc, Inksc return repr; } -gchar* SPFlowregion::description() { +const char* SPFlowregion::displayName() { // TRANSLATORS: "Flow region" is an area where text is allowed to flow - return g_strdup_printf(_("Flow region")); + return _("Flow Region"); } -/* - * - */ SPFlowregionExclude::SPFlowregionExclude() : SPItem() { this->computed = NULL; } @@ -338,18 +335,14 @@ Inkscape::XML::Node *SPFlowregionExclude::write(Inkscape::XML::Document *xml_doc return repr; } -gchar* SPFlowregionExclude::description() { +const char* SPFlowregionExclude::displayName() { /* TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the * flow excluded region. flowRegionExclude in SVG 1.2: see * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. */ - return g_strdup_printf(_("Flow excluded region")); + return _("Flow Excluded Region"); } -/* - * - */ - static void UnionShape(Shape **base_shape, Shape const *add_shape) { if (*base_shape == NULL) diff --git a/src/sp-flowregion.h b/src/sp-flowregion.h index 59818651a..111a32c6c 100644 --- a/src/sp-flowregion.h +++ b/src/sp-flowregion.h @@ -31,7 +31,7 @@ public: virtual void update(SPCtx *ctx, unsigned int flags); virtual void modified(guint flags); virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual gchar *description(); + virtual const char* displayName(); }; class SPFlowregionExclude : public SPItem { @@ -48,7 +48,7 @@ public: virtual void update(SPCtx *ctx, unsigned int flags); virtual void modified(guint flags); virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual gchar *description(); + virtual const char* displayName(); }; #endif diff --git a/src/sp-flowtext.h b/src/sp-flowtext.h index bd7c5990a..f56cba3cd 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); @@ -66,6 +73,7 @@ public: virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type); virtual void print(SPPrintContext *ctx); + virtual const char* displayName(); virtual gchar* description(); virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void hide(unsigned int key); diff --git a/src/sp-gradient-spread.h b/src/sp-gradient-spread.h index cc74ef614..60e33b7c0 100644 --- a/src/sp-gradient-spread.h +++ b/src/sp-gradient-spread.h @@ -4,7 +4,8 @@ enum SPGradientSpread { SP_GRADIENT_SPREAD_PAD, SP_GRADIENT_SPREAD_REFLECT, - SP_GRADIENT_SPREAD_REPEAT + SP_GRADIENT_SPREAD_REPEAT, + SP_GRADIENT_SPREAD_UNDEFINED = INT_MAX }; diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 039edc90f..83d2d8e78 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]); @@ -470,7 +470,7 @@ char *sp_guide_description(SPGuide const *guide, const bool verbose) char *descr = 0; if ( !guide->document ) { // Guide has probably been deleted and no longer has an attached namedview. - descr = g_strdup_printf(_("Deleted")); + descr = g_strdup_printf("%s", _("Deleted")); } else { SPNamedView *namedview = sp_document_namedview(guide->document, NULL); diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 80daf33c3..05dfb5f48 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -78,9 +78,6 @@ static void sp_image_set_curve(SPImage *image); static Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base ); static void sp_image_update_arenaitem (SPImage *img, Inkscape::DrawingImage *ai); static void sp_image_update_canvas_image (SPImage *image); -static GdkPixbuf * sp_image_repr_read_dataURI (const gchar * uri_data); -static GdkPixbuf * sp_image_repr_read_b64 (const gchar * uri_data); -static void pixbuf_set_mime_data(GdkPixbuf *pb, guchar *data, gsize len, GdkPixbufFormat *fmt); #ifdef DEBUG_LCMS extern guint update_in_progress; @@ -613,6 +610,10 @@ void SPImage::print(SPPrintContext *ctx) { } } +const char* SPImage::displayName() { + return _("Image"); +} + gchar* SPImage::description() { char *href_desc; @@ -626,8 +627,8 @@ gchar* SPImage::description() { } char *ret = ( this->pixbuf == NULL - ? g_strdup_printf(_("<b>Image with bad reference</b>: %s"), href_desc) - : g_strdup_printf(_("<b>Image</b> %d × %d: %s"), + ? g_strdup_printf(_("[bad reference]: %s"), href_desc) + : g_strdup_printf(_("%d × %d: %s"), this->pixbuf->width(), this->pixbuf->height(), href_desc) ); diff --git a/src/sp-image.h b/src/sp-image.h index bfc10e7f2..b5834c988 100644 --- a/src/sp-image.h +++ b/src/sp-image.h @@ -64,6 +64,7 @@ public: virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type); virtual void print(SPPrintContext *ctx); + virtual const char* displayName(); virtual gchar* description(); virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); diff --git a/src/sp-item-group.h b/src/sp-item-group.h index 88ca9657a..3954a5d21 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); @@ -75,6 +76,7 @@ public: virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype); virtual void print(SPPrintContext *ctx); + virtual const char* displayName(); virtual gchar *description(); virtual Inkscape::DrawingItem *show (Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void hide (unsigned int key); diff --git a/src/sp-item.cpp b/src/sp-item.cpp index e6991a1fa..bdcbefbba 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 @@ -606,8 +608,8 @@ void SPItem::update(SPCtx *ctx, guint flags) { Geom::OptRect item_bbox = item->visualBounds(); SPItemView *itemview = item->display; do { - if (itemview->arenaitem) - itemview->arenaitem->setItemBounds(item_bbox); + if (itemview->arenaitem) // Already enlarged by visualBounds + itemview->arenaitem->setFilterBounds(item_bbox); } while ( (itemview = itemview->next) ); } @@ -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; @@ -931,9 +933,12 @@ void SPItem::invoke_print(SPPrintContext *ctx) } } -// CPPIFY: is it possible to combine this method with "SPItem::description()"? +const char* SPItem::displayName() { + return _("Object"); +} + gchar* SPItem::description() { - return g_strdup(_("Object")); + return g_strdup(""); } /** @@ -941,9 +946,10 @@ gchar* SPItem::description() { * * Must be freed by caller. */ -gchar *SPItem::getDetailedDescription() +gchar *SPItem::detailedDescription() { - gchar* s = this->description(); + gchar* s = g_strdup_printf("<b>%s</b> %s", + this->displayName(), this->description()); if (s && clip_ref->getObject()) { gchar *snew = g_strdup_printf (_("%s; <i>clipped</i>"), s); @@ -1059,7 +1065,8 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned item_bbox = visualBounds(); } ai->setData(this); - ai->setItemBounds(item_bbox); + // Already enlarged by visualBounds for filters + ai->setFilterBounds(item_bbox); } return ai; @@ -1496,7 +1503,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-item.h b/src/sp-item.h index 8dfb4142a..ce5400e66 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -188,7 +188,7 @@ public: Geom::OptRect desktopBounds(BBoxType type) const; unsigned pos_in_parent(); - gchar *getDetailedDescription(); + gchar *detailedDescription(); int ifilt(); void invoke_print(SPPrintContext *ctx); static unsigned int display_key_new(unsigned int numkeys); @@ -236,6 +236,7 @@ public: virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type); virtual void print(SPPrintContext *ctx); + virtual const char* displayName(); virtual gchar* description(); virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void hide(unsigned int key); diff --git a/src/sp-line.cpp b/src/sp-line.cpp index 3963007de..6b7df84f6 100644 --- a/src/sp-line.cpp +++ b/src/sp-line.cpp @@ -122,8 +122,8 @@ Inkscape::XML::Node* SPLine::write(Inkscape::XML::Document *xml_doc, Inkscape::X return repr; } -gchar* SPLine::description() { - return g_strdup(_("<b>Line</b>")); +const char* SPLine::displayName() { + return _("Line"); } void SPLine::convert_to_guides() { diff --git a/src/sp-line.h b/src/sp-line.h index ebdfc9f04..f76c3449b 100644 --- a/src/sp-line.h +++ b/src/sp-line.h @@ -34,7 +34,7 @@ public: virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); virtual void set(unsigned int key, gchar const* value); - virtual gchar* description(); + virtual const char* displayName(); virtual Geom::Affine set_transform(Geom::Affine const &transform); virtual void convert_to_guides(); virtual void update(SPCtx* ctx, guint flags); diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 895b36e1c..6fd4de43b 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -61,6 +61,14 @@ using std::strstr; # define debug(f, a...) /* */ #endif +namespace { + SPObject* createObject() { + return new SPObject(); + } + + bool gridRegistered = SPFactory::instance().registerObject("inkscape:grid", createObject); +} + guint update_in_progress = 0; // guard against update-during-update Inkscape::XML::NodeEventVector object_event_vector = { @@ -588,9 +596,14 @@ void SPObject::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) ochild->invoke_build(object->document, child, object->cloned); } catch (const FactoryExceptions::TypeNotRegistered& e) { - if (std::string(e.what()) != "rdf:RDF") { // temporary special case - g_warning("TypeNotRegistered exception: %s", e.what()); - } + std::string node = e.what(); + + // special cases + if (node.empty()) return; // comments, usually + if (node == "rdf:RDF") return; // no SP node yet + if (node == "inkscape:clipboard") return; // SP node not necessary + + g_warning("TypeNotRegistered exception: %s", e.what()); } } @@ -635,27 +648,21 @@ void SPObject::build(SPDocument *document, Inkscape::XML::Node *repr) { object->readAttr("inkscape:collect"); for (Inkscape::XML::Node *rchild = repr->firstChild() ; rchild != NULL; rchild = rchild->next()) { -// GType type = sp_repr_type_lookup(rchild); -// if (!type) { -// continue; -// } -// SPObject *child = SP_OBJECT(g_object_new(type, 0)); - -// SPObject* child = SPFactory::instance().createObject(*rchild); -// if (!child) { -// continue; -// } - try { const std::string typeString = NodeTraits::get_type_string(*rchild); + // special cases + if (typeString.empty()) continue; // comments, usually + if (typeString == "rdf:RDF") continue; // no SP node yet + if (typeString == "inkscape:clipboard") continue; // SP node not necessary + SPObject* child = SPFactory::instance().createObject(typeString); object->attach(child, object->lastChild()); sp_object_unref(child, NULL); child->invoke_build(document, rchild, object->cloned); } catch (const FactoryExceptions::TypeNotRegistered& e) { - //g_warning("TypeNotRegistered exception: %s", e.what()); + g_warning("TypeNotRegistered exception: %s", e.what()); } } } diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp index ef18acc8e..f0b152d0e 100644 --- a/src/sp-offset.cpp +++ b/src/sp-offset.cpp @@ -339,18 +339,20 @@ void SPOffset::update(SPCtx *ctx, guint flags) { SPShape::update(ctx, flags); } -gchar* SPOffset::description() { +const char* SPOffset::displayName() { if ( this->sourceHref ) { - // TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign - return g_strdup_printf(_("<b>Linked offset</b>, %s by %f pt"), - (this->rad >= 0)? _("outset") : _("inset"), fabs (this->rad)); + return _("Linked Offset"); } else { - // TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign - return g_strdup_printf(_("<b>Dynamic offset</b>, %s by %f pt"), - (this->rad >= 0)? _("outset") : _("inset"), fabs (this->rad)); + return _("Dynamic Offset"); } } +gchar* SPOffset::description() { + // TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign + return g_strdup_printf(_("%s by %f pt"), (this->rad >= 0) ? + _("outset") : _("inset"), fabs (this->rad)); +} + void SPOffset::set_shape() { if ( this->originalPath == NULL ) { // oops : no path?! (the offset object should do harakiri) diff --git a/src/sp-offset.h b/src/sp-offset.h index 7fe6a8a24..b93a6846b 100644 --- a/src/sp-offset.h +++ b/src/sp-offset.h @@ -82,6 +82,7 @@ public: virtual void release(); virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); + virtual const char* displayName(); virtual gchar* description(); virtual void set_shape(); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 105506d6e..6a503c6b2 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -66,8 +66,13 @@ gint SPPath::nodesInPath() const return _curve ? _curve->nodes_in_path() : 0; } +const char* SPPath::displayName() { + return _("Path"); +} + gchar* SPPath::description() { int count = this->nodesInPath(); + char *lpe_desc = g_strdup(""); if (sp_lpe_item_has_path_effect(this)) { Glib::ustring s; @@ -87,13 +92,12 @@ gchar* SPPath::description() { s = s + ", " + lpeobj->get_lpe()->getName(); } } - - return g_strdup_printf(ngettext("<b>Path</b> (%i node, path effect: %s)", - "<b>Path</b> (%i nodes, path effect: %s)",count), count, s.c_str()); - } else { - return g_strdup_printf(ngettext("<b>Path</b> (%i node)", - "<b>Path</b> (%i nodes)",count), count); + lpe_desc = g_strdup_printf(_(", path effect: %s"), s.c_str()); } + char *ret = g_strdup_printf(ngettext( + _("%i node%s"), _("%i nodes%s"), count), count, lpe_desc); + g_free(lpe_desc); + return ret; } void SPPath::convert_to_guides() { diff --git a/src/sp-path.h b/src/sp-path.h index 42c0f22c8..77c64a2cc 100644 --- a/src/sp-path.h +++ b/src/sp-path.h @@ -54,6 +54,7 @@ public: virtual void set(unsigned int key, gchar const* value); virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual const char* displayName(); virtual gchar* description(); virtual Geom::Affine set_transform(Geom::Affine const &transform); virtual void convert_to_guides(); diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp index 519b7ba6e..ff5e81f95 100644 --- a/src/sp-rect.cpp +++ b/src/sp-rect.cpp @@ -159,8 +159,8 @@ Inkscape::XML::Node * SPRect::write(Inkscape::XML::Document *xml_doc, Inkscape:: return repr; } -gchar* SPRect::description() { - return g_strdup(_("<b>Rectangle</b>")); +const char* SPRect::displayName() { + return _("Rectangle"); } #define C1 0.554 diff --git a/src/sp-rect.h b/src/sp-rect.h index 28f74f9f9..3219a3ace 100644 --- a/src/sp-rect.h +++ b/src/sp-rect.h @@ -55,7 +55,7 @@ public: virtual void update(SPCtx* ctx, unsigned int flags); virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual gchar* description(); + virtual const char* displayName(); virtual void set_shape(); virtual Geom::Affine set_transform(Geom::Affine const& xform); diff --git a/src/sp-root.cpp b/src/sp-root.cpp index 4faefabef..c87c8397d 100644 --- a/src/sp-root.cpp +++ b/src/sp-root.cpp @@ -34,18 +34,20 @@ #include "sp-factory.h" namespace { - SPObject* createRoot() { - return new SPRoot(); - } +SPObject *createRoot() +{ + return new SPRoot(); +} - bool rootRegistered = SPFactory::instance().registerObject("svg:svg", createRoot); +bool rootRegistered = SPFactory::instance().registerObject("svg:svg", createRoot); } -SPRoot::SPRoot() : SPGroup() { - this->aspect_set = 0; - this->aspect_align = 0; - this->onload = NULL; - this->aspect_clip = 0; +SPRoot::SPRoot() : SPGroup() +{ + this->aspect_set = 0; + this->aspect_align = 0; + this->onload = NULL; + this->aspect_clip = 0; static Inkscape::Version const zero_version(0, 0); @@ -67,30 +69,32 @@ SPRoot::SPRoot() : SPGroup() { this->defs = NULL; } -SPRoot::~SPRoot() { +SPRoot::~SPRoot() +{ } -void SPRoot::build(SPDocument *document, Inkscape::XML::Node *repr) { +void SPRoot::build(SPDocument *document, Inkscape::XML::Node *repr) +{ //XML Tree being used directly here while it shouldn't be. - if ( !this->getRepr()->attribute("version") ) { + if (!this->getRepr()->attribute("version")) { repr->setAttribute("version", SVG_VERSION); } - this->readAttr( "version" ); - this->readAttr( "inkscape:version" ); + this->readAttr("version"); + this->readAttr("inkscape:version"); /* It is important to parse these here, so objects will have viewport build-time */ - this->readAttr( "x" ); - this->readAttr( "y" ); - this->readAttr( "width" ); - this->readAttr( "height" ); - this->readAttr( "viewBox" ); - this->readAttr( "preserveAspectRatio" ); - this->readAttr( "onload" ); + this->readAttr("x"); + this->readAttr("y"); + this->readAttr("width"); + this->readAttr("height"); + this->readAttr("viewBox"); + this->readAttr("preserveAspectRatio"); + this->readAttr("onload"); SPGroup::build(document, repr); // Search for first <defs> node - for (SPObject *o = this->firstChild() ; o ; o = o->getNext() ) { + for (SPObject *o = this->firstChild() ; o ; o = o->getNext()) { if (SP_IS_DEFS(o)) { this->defs = SP_DEFS(o); break; @@ -101,232 +105,239 @@ void SPRoot::build(SPDocument *document, Inkscape::XML::Node *repr) { SP_ITEM(this)->transform = Geom::identity(); } -void SPRoot::release() { +void SPRoot::release() +{ this->defs = NULL; SPGroup::release(); } -void SPRoot::set(unsigned int key, const gchar* value) { +void SPRoot::set(unsigned int key, const gchar *value) +{ switch (key) { - case SP_ATTR_VERSION: - if (!sp_version_from_string(value, &this->version.svg)) { - this->version.svg = this->original.svg; - } - break; + case SP_ATTR_VERSION: + if (!sp_version_from_string(value, &this->version.svg)) { + this->version.svg = this->original.svg; + } + break; - case SP_ATTR_INKSCAPE_VERSION: - if (!sp_version_from_string(value, &this->version.inkscape)) { - this->version.inkscape = this->original.inkscape; - } - break; + case SP_ATTR_INKSCAPE_VERSION: + if (!sp_version_from_string(value, &this->version.inkscape)) { + this->version.inkscape = this->original.inkscape; + } + break; - case SP_ATTR_X: - if (!this->x.readAbsolute(value)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - this->x.unset(); - } + case SP_ATTR_X: + if (!this->x.readAbsolute(value)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + this->x.unset(); + } - /* fixme: I am almost sure these do not require viewport flag (Lauris) */ - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; + /* fixme: I am almost sure these do not require viewport flag (Lauris) */ + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; - case SP_ATTR_Y: - if (!this->y.readAbsolute(value)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - this->y.unset(); - } + case SP_ATTR_Y: + if (!this->y.readAbsolute(value)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + this->y.unset(); + } - /* fixme: I am almost sure these do not require viewport flag (Lauris) */ - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; + /* fixme: I am almost sure these do not require viewport flag (Lauris) */ + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; - case SP_ATTR_WIDTH: - if (!this->width.readAbsolute(value) || !(this->width.computed > 0.0)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - this->width.unset(SVGLength::PERCENT, 1.0, 1.0); - } + case SP_ATTR_WIDTH: + if (!this->width.readAbsolute(value) || !(this->width.computed > 0.0)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + this->width.unset(SVGLength::PERCENT, 1.0, 1.0); + } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; - case SP_ATTR_HEIGHT: - if (!this->height.readAbsolute(value) || !(this->height.computed > 0.0)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - this->height.unset(SVGLength::PERCENT, 1.0, 1.0); - } + case SP_ATTR_HEIGHT: + if (!this->height.readAbsolute(value) || !(this->height.computed > 0.0)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + this->height.unset(SVGLength::PERCENT, 1.0, 1.0); + } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; - case SP_ATTR_VIEWBOX: - if (value) { - double x, y, width, height; - char *eptr; + case SP_ATTR_VIEWBOX: + if (value) { + double x, y, width, height; + char *eptr; - /* fixme: We have to take original item affine into account */ - /* fixme: Think (Lauris) */ - eptr = (gchar *) value; - x = g_ascii_strtod(eptr, &eptr); + /* fixme: We have to take original item affine into account */ + /* fixme: Think (Lauris) */ + eptr = (gchar *) value; + x = g_ascii_strtod(eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; + } - y = g_ascii_strtod(eptr, &eptr); + y = g_ascii_strtod(eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; + } - width = g_ascii_strtod(eptr, &eptr); + width = g_ascii_strtod(eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; + } - height = g_ascii_strtod(eptr, &eptr); + height = g_ascii_strtod(eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; + } - if ((width > 0) && (height > 0)) { - /* Set viewbox */ - this->viewBox = Geom::Rect::from_xywh(x, y, width, height); - this->viewBox_set = TRUE; - } else { - this->viewBox_set = FALSE; - } + if ((width > 0) && (height > 0)) { + /* Set viewbox */ + this->viewBox = Geom::Rect::from_xywh(x, y, width, height); + this->viewBox_set = TRUE; } else { this->viewBox_set = FALSE; } + } else { + this->viewBox_set = FALSE; + } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; - case SP_ATTR_PRESERVEASPECTRATIO: - /* Do setup before, so we can use break to escape */ - this->aspect_set = FALSE; - this->aspect_align = SP_ASPECT_XMID_YMID; - this->aspect_clip = SP_ASPECT_MEET; + case SP_ATTR_PRESERVEASPECTRATIO: + /* Do setup before, so we can use break to escape */ + this->aspect_set = FALSE; + this->aspect_align = SP_ASPECT_XMID_YMID; + this->aspect_clip = SP_ASPECT_MEET; - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - if (value) { - int len; - gchar c[256]; - gchar const *p, *e; - unsigned int align, clip; - p = value; + if (value) { + int len; + gchar c[256]; + gchar const *p, *e; + unsigned int align, clip; + p = value; - while (*p && *p == 32) { - p += 1; - } + while (*p && *p == 32) { + p += 1; + } - if (!*p) { - break; - } + if (!*p) { + break; + } - e = p; + e = p; - while (*e && *e != 32) { - e += 1; - } + while (*e && *e != 32) { + e += 1; + } - len = e - p; + len = e - p; - if (len > 8) { - break; - } + if (len > 8) { + break; + } - memcpy(c, value, len); - - c[len] = 0; - - /* Now the actual part */ - if (!strcmp(c, "none")) { - align = SP_ASPECT_NONE; - } else if (!strcmp(c, "xMinYMin")) { - align = SP_ASPECT_XMIN_YMIN; - } else if (!strcmp(c, "xMidYMin")) { - align = SP_ASPECT_XMID_YMIN; - } else if (!strcmp(c, "xMaxYMin")) { - align = SP_ASPECT_XMAX_YMIN; - } else if (!strcmp(c, "xMinYMid")) { - align = SP_ASPECT_XMIN_YMID; - } else if (!strcmp(c, "xMidYMid")) { - align = SP_ASPECT_XMID_YMID; - } else if (!strcmp(c, "xMaxYMid")) { - align = SP_ASPECT_XMAX_YMID; - } else if (!strcmp(c, "xMinYMax")) { - align = SP_ASPECT_XMIN_YMAX; - } else if (!strcmp(c, "xMidYMax")) { - align = SP_ASPECT_XMID_YMAX; - } else if (!strcmp(c, "xMaxYMax")) { - align = SP_ASPECT_XMAX_YMAX; - } else { - break; - } + memcpy(c, value, len); + + c[len] = 0; + + /* Now the actual part */ + if (!strcmp(c, "none")) { + align = SP_ASPECT_NONE; + } else if (!strcmp(c, "xMinYMin")) { + align = SP_ASPECT_XMIN_YMIN; + } else if (!strcmp(c, "xMidYMin")) { + align = SP_ASPECT_XMID_YMIN; + } else if (!strcmp(c, "xMaxYMin")) { + align = SP_ASPECT_XMAX_YMIN; + } else if (!strcmp(c, "xMinYMid")) { + align = SP_ASPECT_XMIN_YMID; + } else if (!strcmp(c, "xMidYMid")) { + align = SP_ASPECT_XMID_YMID; + } else if (!strcmp(c, "xMaxYMid")) { + align = SP_ASPECT_XMAX_YMID; + } else if (!strcmp(c, "xMinYMax")) { + align = SP_ASPECT_XMIN_YMAX; + } else if (!strcmp(c, "xMidYMax")) { + align = SP_ASPECT_XMID_YMAX; + } else if (!strcmp(c, "xMaxYMax")) { + align = SP_ASPECT_XMAX_YMAX; + } else { + break; + } - clip = SP_ASPECT_MEET; + clip = SP_ASPECT_MEET; - while (*e && *e == 32) { - e += 1; - } + while (*e && *e == 32) { + e += 1; + } - if (*e) { - if (!strcmp(e, "meet")) { - clip = SP_ASPECT_MEET; - } else if (!strcmp(e, "slice")) { - clip = SP_ASPECT_SLICE; - } else { - break; - } + if (*e) { + if (!strcmp(e, "meet")) { + clip = SP_ASPECT_MEET; + } else if (!strcmp(e, "slice")) { + clip = SP_ASPECT_SLICE; + } else { + break; } - - this->aspect_set = TRUE; - this->aspect_align = align; - this->aspect_clip = clip; } - break; - case SP_ATTR_ONLOAD: - this->onload = (char *) value; - break; + this->aspect_set = TRUE; + this->aspect_align = align; + this->aspect_clip = clip; + } + break; - default: - /* Pass the set event to the parent */ - SPGroup::set(key, value); - break; + case SP_ATTR_ONLOAD: + this->onload = (char *) value; + break; + + default: + /* Pass the set event to the parent */ + SPGroup::set(key, value); + break; } } -void SPRoot::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) { +void SPRoot::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ SPGroup::child_added(child, ref); SPObject *co = this->document->getObjectByRepr(child); - g_assert (co != NULL || !strcmp("comment", child->name())); // comment repr node has no object + // NOTE: some XML nodes do not have corresponding SP objects, + // for instance inkscape:clipboard used in the clipboard code. + // See LP bug #1227827 + //g_assert (co != NULL || !strcmp("comment", child->name())); // comment repr node has no object if (co && SP_IS_DEFS(co)) { // We search for first <defs> node - it is not beautiful, but works - for (SPObject *c = this->firstChild() ; c ; c = c->getNext() ) { + for (SPObject *c = this->firstChild() ; c ; c = c->getNext()) { if (SP_IS_DEFS(c)) { - this->defs = SP_DEFS(c); + this->defs = SP_DEFS(c); break; } } } } -void SPRoot::remove_child(Inkscape::XML::Node* child) { - if ( this->defs && (this->defs->getRepr() == child) ) { +void SPRoot::remove_child(Inkscape::XML::Node *child) +{ + if (this->defs && (this->defs->getRepr() == child)) { SPObject *iter = 0; // We search for first remaining <defs> node - it is not beautiful, but works - for ( iter = this->firstChild() ; iter ; iter = iter->getNext() ) { - if ( SP_IS_DEFS(iter) && (SPDefs *)iter != this->defs ) { + for (iter = this->firstChild() ; iter ; iter = iter->getNext()) { + if (SP_IS_DEFS(iter) && (SPDefs *)iter != this->defs) { this->defs = (SPDefs *)iter; break; } @@ -341,14 +352,15 @@ void SPRoot::remove_child(Inkscape::XML::Node* child) { SPGroup::remove_child(child); } -void SPRoot::update(SPCtx *ctx, guint flags) { +void SPRoot::update(SPCtx *ctx, guint flags) +{ SPItemCtx *ictx = (SPItemCtx *) ctx; /* fixme: This will be invoked too often (Lauris) */ /* fixme: We should calculate only if parent viewport has changed (Lauris) */ /* If position is specified as percentage, calculate actual values */ if (this->x.unit == SVGLength::PERCENT) { - this->x.computed = this->x.value * ictx->viewport.width(); + this->x.computed = this->x.value * ictx->viewport.width(); } if (this->y.unit == SVGLength::PERCENT) { @@ -377,7 +389,7 @@ void SPRoot::update(SPCtx *ctx, guint flags) { * fixme: height seems natural, as this makes the inner svg element * fixme: self-contained. The spec is vague here. */ - this->c2p = Geom::Affine(Geom::Translate(this->x.computed, this->y.computed)); + this->c2p = Geom::Affine(Geom::Translate(this->x.computed, this->y.computed)); } if (this->viewBox_set) { @@ -401,66 +413,66 @@ void SPRoot::update(SPCtx *ctx, guint flags) { /* todo: Use an array lookup to find the 0.0/0.5/1.0 coefficients, as is done for dialogs/align.cpp. */ switch (this->aspect_align) { - case SP_ASPECT_XMIN_YMIN: - x = 0.0; - y = 0.0; - break; + case SP_ASPECT_XMIN_YMIN: + x = 0.0; + y = 0.0; + break; - case SP_ASPECT_XMID_YMIN: - x = 0.5 * (this->width.computed - width); - y = 0.0; - break; + case SP_ASPECT_XMID_YMIN: + x = 0.5 * (this->width.computed - width); + y = 0.0; + break; - case SP_ASPECT_XMAX_YMIN: - x = 1.0 * (this->width.computed - width); - y = 0.0; - break; + case SP_ASPECT_XMAX_YMIN: + x = 1.0 * (this->width.computed - width); + y = 0.0; + break; - case SP_ASPECT_XMIN_YMID: - x = 0.0; - y = 0.5 * (this->height.computed - height); - break; + case SP_ASPECT_XMIN_YMID: + x = 0.0; + y = 0.5 * (this->height.computed - height); + break; - case SP_ASPECT_XMID_YMID: - x = 0.5 * (this->width.computed - width); - y = 0.5 * (this->height.computed - height); - break; + case SP_ASPECT_XMID_YMID: + x = 0.5 * (this->width.computed - width); + y = 0.5 * (this->height.computed - height); + break; - case SP_ASPECT_XMAX_YMID: - x = 1.0 * (this->width.computed - width); - y = 0.5 * (this->height.computed - height); - break; + case SP_ASPECT_XMAX_YMID: + x = 1.0 * (this->width.computed - width); + y = 0.5 * (this->height.computed - height); + break; - case SP_ASPECT_XMIN_YMAX: - x = 0.0; - y = 1.0 * (this->height.computed - height); - break; + case SP_ASPECT_XMIN_YMAX: + x = 0.0; + y = 1.0 * (this->height.computed - height); + break; - case SP_ASPECT_XMID_YMAX: - x = 0.5 * (this->width.computed - width); - y = 1.0 * (this->height.computed - height); - break; + case SP_ASPECT_XMID_YMAX: + x = 0.5 * (this->width.computed - width); + y = 1.0 * (this->height.computed - height); + break; - case SP_ASPECT_XMAX_YMAX: - x = 1.0 * (this->width.computed - width); - y = 1.0 * (this->height.computed - height); - break; + case SP_ASPECT_XMAX_YMAX: + x = 1.0 * (this->width.computed - width); + y = 1.0 * (this->height.computed - height); + break; - default: - x = 0.0; - y = 0.0; - break; + default: + x = 0.0; + y = 0.0; + break; } } /* Compose additional transformation from scale and position */ - Geom::Scale const viewBox_length( this->viewBox.dimensions() ); + Geom::Scale const viewBox_length(this->viewBox.dimensions()); Geom::Scale const new_length(width, height); /* Append viewbox transformation */ /* TODO: The below looks suspicious to me (pjrm): I wonder whether the RHS expression should have c2p at the beginning rather than at the end. Test it. */ - this->c2p = Geom::Translate(-this->viewBox.min()) * ( new_length * viewBox_length.inverse() ) * Geom::Translate(x, y) * this->c2p; + this->c2p = Geom::Translate(-this->viewBox.min()) * (new_length * viewBox_length.inverse()) * Geom::Translate(x, y) * this->c2p; } rctx.i2doc = this->c2p * rctx.i2doc; @@ -470,7 +482,7 @@ void SPRoot::update(SPCtx *ctx, guint flags) { rctx.viewport = this->viewBox; } else { /* fixme: I wonder whether this logic is correct (Lauris) */ - Geom::Point minp(0,0); + Geom::Point minp(0, 0); if (this->parent) { minp = Geom::Point(this->x.computed, this->y.computed); } @@ -490,17 +502,19 @@ void SPRoot::update(SPCtx *ctx, guint flags) { } } -void SPRoot::modified(unsigned int flags) { +void SPRoot::modified(unsigned int flags) +{ SPGroup::modified(flags); /* fixme: (Lauris) */ if (!this->parent && (flags & SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { - this->document->emitResizedSignal(this->width.computed, this->height.computed); + this->document->emitResizedSignal(this->width.computed, this->height.computed); } } -Inkscape::XML::Node* SPRoot::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { +Inkscape::XML::Node *SPRoot::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:svg"); } @@ -509,8 +523,8 @@ Inkscape::XML::Node* SPRoot::write(Inkscape::XML::Document *xml_doc, Inkscape::X repr->setAttribute("inkscape:version", Inkscape::version_string); } - if ( !repr->attribute("version") ) { - gchar* myversion = sp_version_to_string(this->version.svg); + if (!repr->attribute("version")) { + gchar *myversion = sp_version_to_string(this->version.svg); repr->setAttribute("version", myversion); g_free(myversion); } @@ -542,20 +556,22 @@ Inkscape::XML::Node* SPRoot::write(Inkscape::XML::Document *xml_doc, Inkscape::X return repr; } -Inkscape::DrawingItem* SPRoot::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { +Inkscape::DrawingItem *SPRoot::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) +{ Inkscape::DrawingItem *ai = 0; ai = SPGroup::show(drawing, key, flags); if (ai) { - Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(ai); - g->setChildTransform(this->c2p); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(ai); + g->setChildTransform(this->c2p); } return ai; } -void SPRoot::print(SPPrintContext* ctx) { +void SPRoot::print(SPPrintContext *ctx) +{ sp_print_bind(ctx, this->c2p, 1.0); SPGroup::print(ctx); 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 8d2954c6e..0c5ef253f 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -28,7 +28,6 @@ #include "sp-spiral.h" - #include "sp-factory.h" namespace { @@ -227,12 +226,14 @@ void SPSpiral::update_patheffect(bool write) { shape->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } -gchar* SPSpiral::description() { - SPSpiral* item = this; +const char* SPSpiral::displayName() { + return _("Spiral"); +} - // TRANSLATORS: since turn count isn't an integer, please adjust the +gchar* SPSpiral::description() { + // TRANSLATORS: since turn count isn't an integer, please adjust the // string as needed to deal with an localized plural forms. - return g_strdup_printf (_("<b>Spiral</b> with %3f turns"), SP_SPIRAL(item)->revo); + return g_strdup_printf (_("with %3f turns"), SP_SPIRAL(this)->revo); } /** @@ -433,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 1e9c2d2b4..a81b4a3dd 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; @@ -71,6 +72,7 @@ public: virtual void set(unsigned int key, gchar const* value); virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); + virtual const char* displayName(); virtual gchar* description(); virtual void set_shape(); diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 4a3a8cbe3..10c3267b2 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -251,19 +251,18 @@ void SPStar::update_patheffect(bool write) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } +const char* SPStar::displayName() { + if (this->flatsided == false) + return _("Star"); + return _("Polygon"); +} + gchar* SPStar::description() { // while there will never be less than 3 vertices, we still need to // make calls to ngettext because the pluralization may be different // for various numbers >=3. The singular form is used as the index. - if (this->flatsided == false) { - return g_strdup_printf (ngettext("<b>Star</b> with %d vertex", - "<b>Star</b> with %d vertices", - this->sides), this->sides); - } else { - return g_strdup_printf (ngettext("<b>Polygon</b> with %d vertex", - "<b>Polygon</b> with %d vertices", - this->sides), this->sides); - } + return g_strdup_printf (ngettext(_("with %d vertex"), _("with %d vertices"), + this->sides), this->sides); } /** @@ -515,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 0f1280139..799880c42 100644 --- a/src/sp-star.h +++ b/src/sp-star.h @@ -50,11 +50,13 @@ public: virtual void set(unsigned int key, gchar const* value); virtual void update(SPCtx* ctx, guint flags); + virtual const char* displayName(); virtual gchar* description(); virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); 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-style-elem-test.h b/src/sp-style-elem-test.h index 7021be13d..6f65a48ea 100644 --- a/src/sp-style-elem-test.h +++ b/src/sp-style-elem-test.h @@ -28,12 +28,13 @@ public: static void createSuiteSubclass( SPStyleElemTest *& dst ) { - SPStyleElem *style_elem = static_cast<SPStyleElem *>(g_object_new(SP_TYPE_STYLE_ELEM, NULL)); + SPStyleElem *style_elem = new SPStyleElem(); + if ( style_elem ) { TS_ASSERT(!style_elem->is_css); TS_ASSERT(style_elem->media.print); TS_ASSERT(style_elem->media.screen); - g_object_unref(style_elem); + delete style_elem; dst = new SPStyleElemTest(); } @@ -52,7 +53,7 @@ public: void testSetType() { - SPStyleElem *style_elem = static_cast<SPStyleElem *>(g_object_new(SP_TYPE_STYLE_ELEM, NULL)); + SPStyleElem *style_elem = new SPStyleElem(); SP_OBJECT(style_elem)->document = _doc; SP_OBJECT(style_elem)->setKeyValue( SP_ATTR_TYPE, "something unrecognized"); @@ -67,7 +68,7 @@ public: SP_OBJECT(style_elem)->setKeyValue( SP_ATTR_TYPE, "text/cssx"); TS_ASSERT( !style_elem->is_css ); - g_object_unref(style_elem); + delete style_elem; } void testWrite() @@ -78,7 +79,7 @@ public: return; // evil early return } - SPStyleElem *style_elem = SP_STYLE_ELEM(g_object_new(SP_TYPE_STYLE_ELEM, NULL)); + SPStyleElem *style_elem = new SPStyleElem(); SP_OBJECT(style_elem)->document = _doc; SP_OBJECT(style_elem)->setKeyValue( SP_ATTR_TYPE, "text/css"); @@ -93,7 +94,7 @@ public: } } - g_object_unref(style_elem); + delete style_elem; } void testBuild() @@ -104,13 +105,13 @@ public: return; // evil early return } - SPStyleElem &style_elem = *SP_STYLE_ELEM(g_object_new(SP_TYPE_STYLE_ELEM, NULL)); + SPStyleElem *style_elem = new SPStyleElem(); Inkscape::XML::Node *const repr = _doc->getReprDoc()->createElement("svg:style"); repr->setAttribute("type", "text/css"); - (&style_elem)->invoke_build( _doc, repr, false); - TS_ASSERT( style_elem.is_css ); - TS_ASSERT( style_elem.media.print ); - TS_ASSERT( style_elem.media.screen ); + style_elem->invoke_build( _doc, repr, false); + TS_ASSERT( style_elem->is_css ); + TS_ASSERT( style_elem->media.print ); + TS_ASSERT( style_elem->media.screen ); /* Some checks relevant to the read_content test below. */ { @@ -120,7 +121,7 @@ public: g_assert(stylesheet->statements == NULL); } - g_object_unref(&style_elem); + delete style_elem; Inkscape::GC::release(repr); } @@ -132,19 +133,19 @@ public: return; // evil early return } - SPStyleElem &style_elem = *SP_STYLE_ELEM(g_object_new(SP_TYPE_STYLE_ELEM, NULL)); + SPStyleElem *style_elem = new SPStyleElem(); Inkscape::XML::Node *const repr = _doc->getReprDoc()->createElement("svg:style"); repr->setAttribute("type", "text/css"); Inkscape::XML::Node *const content_repr = _doc->getReprDoc()->createTextNode(".myclass { }"); repr->addChild(content_repr, NULL); - (&style_elem)->invoke_build(_doc, repr, false); - TS_ASSERT( style_elem.is_css ); + style_elem->invoke_build(_doc, repr, false); + TS_ASSERT( style_elem->is_css ); TS_ASSERT( _doc->style_cascade ); CRStyleSheet const *const stylesheet = cr_cascade_get_sheet(_doc->style_cascade, ORIGIN_AUTHOR); TS_ASSERT(stylesheet != NULL); TS_ASSERT(stylesheet->statements != NULL); - g_object_unref(&style_elem); + delete style_elem; Inkscape::GC::release(repr); } diff --git a/src/sp-switch.cpp b/src/sp-switch.cpp index cc50a8fef..fa97cde91 100644 --- a/src/sp-switch.cpp +++ b/src/sp-switch.cpp @@ -71,12 +71,14 @@ GSList *SPSwitch::_childList(bool add_ref, SPObject::Action action) { return g_slist_prepend (NULL, child); } +const char *SPSwitch::displayName() { + return _("Conditional Group"); +} + gchar *SPSwitch::description() { gint len = this->getItemCount(); return g_strdup_printf( - ngettext("<b>Conditional group</b> of <b>%d</b> object", - "<b>Conditional group</b> of <b>%d</b> objects", - len), len); + ngettext(_("of <b>%d</b> object"), _("of <b>%d</b> objects"), len), len); } void SPSwitch::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) { diff --git a/src/sp-switch.h b/src/sp-switch.h index 210cd0ddc..e6dc6f01f 100644 --- a/src/sp-switch.h +++ b/src/sp-switch.h @@ -41,6 +41,7 @@ public: virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); virtual void remove_child(Inkscape::XML::Node *child); virtual void order_changed(Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref); + virtual const char* displayName(); virtual gchar *description(); }; diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 85137e58d..72a5996d1 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -321,6 +321,9 @@ void SPText::hide(unsigned int key) { // SPItem::onHide(key); } +const char* SPText::displayName() { + return _("Text"); +} gchar* SPText::description() { SPStyle *style = this->style; @@ -350,8 +353,8 @@ gchar* SPText::description() { } char *ret = ( SP_IS_TEXT_TEXTPATH(this) - ? g_strdup_printf(_("<b>Text on path</b>%s (%s, %s)"), trunc, n, xs->str) - : g_strdup_printf(_("<b>Text</b>%s (%s, %s)"), trunc, n, xs->str) ); + ? g_strdup_printf(_("on path%s (%s, %s)"), trunc, n, xs->str) + : g_strdup_printf(_("%s (%s, %s)"), trunc, n, xs->str) ); g_free(n); return ret; } @@ -374,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 12f773ded..a7149159a 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); @@ -78,6 +84,7 @@ public: virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type); virtual void print(SPPrintContext *ctx); + virtual const char* displayName(); virtual gchar* description(); virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void hide(unsigned int key); diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp index 1872cdf7c..4f9947a04 100644 --- a/src/sp-tref.cpp +++ b/src/sp-tref.cpp @@ -233,28 +233,30 @@ Geom::OptRect SPTRef::bbox(Geom::Affine const &transform, SPItem::BBoxType type) return bbox; } +const char* SPTRef::displayName() { + return _("Cloned Character Data"); +} + gchar* SPTRef::description() { - SPObject *referred = this->getObjectReferredTo(); + SPObject *referred = this->getObjectReferredTo(); - if (this->getObjectReferredTo()) { - char *child_desc; + if (this->getObjectReferredTo()) { + char *child_desc; - if (SP_IS_ITEM(referred)) { - child_desc = SP_ITEM(referred)->getDetailedDescription(); - } else { - child_desc = g_strdup(""); - } + if (SP_IS_ITEM(referred)) { + child_desc = SP_ITEM(referred)->detailedDescription(); + } else { + child_desc = g_strdup(""); + } - char *ret = g_strdup_printf( - _("<b>Cloned character data</b>%s%s"), - (SP_IS_ITEM(referred) ? _(" from ") : ""), - child_desc); - g_free(child_desc); + char *ret = g_strdup_printf("%s%s", + (SP_IS_ITEM(referred) ? _(" from ") : ""), child_desc); + g_free(child_desc); - return ret; - } + return ret; + } - return g_strdup(_("<b>Orphaned cloned character data</b>")); + return g_strdup(_("[orphaned]")); } diff --git a/src/sp-tref.h b/src/sp-tref.h index 451c6cb58..6d43d679d 100644 --- a/src/sp-tref.h +++ b/src/sp-tref.h @@ -58,6 +58,7 @@ public: virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type); + virtual const char* displayName(); virtual gchar* description(); }; diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index 63dcd07d8..21c5ee11f 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -216,8 +216,8 @@ Inkscape::XML::Node* SPTSpan::write(Inkscape::XML::Document *xml_doc, Inkscape:: return repr; } -gchar* SPTSpan::description() { - return g_strdup(_("<b>Text span</b>")); +const char* SPTSpan::displayName() { + return _("Text Span"); } diff --git a/src/sp-tspan.h b/src/sp-tspan.h index d1c6ec4bc..a7ae563bb 100644 --- a/src/sp-tspan.h +++ b/src/sp-tspan.h @@ -34,7 +34,7 @@ public: virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type); - virtual gchar* description(); + virtual const char* displayName(); }; #endif /* !INKSCAPE_SP_TSPAN_H */ 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/spray-context.cpp b/src/spray-context.cpp index 51fdab6ff..08dc59bce 100644 --- a/src/spray-context.cpp +++ b/src/spray-context.cpp @@ -186,7 +186,7 @@ void SPSprayContext::update_cursor(bool /*with_shift*/) { num = g_slist_length(const_cast<GSList *>(desktop->selection->itemList())); sel_message = g_strdup_printf(ngettext("<b>%i</b> object selected","<b>%i</b> objects selected",num), num); } else { - sel_message = g_strdup_printf(_("<b>Nothing</b> selected")); + sel_message = g_strdup_printf("%s", _("<b>Nothing</b> selected")); } switch (this->mode) { 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/svg/CMakeLists.txt b/src/svg/CMakeLists.txt index 943c3088f..968287895 100644 --- a/src/svg/CMakeLists.txt +++ b/src/svg/CMakeLists.txt @@ -1,10 +1,7 @@ set(svg_SRC css-ostringstream.cpp - #ftos.cpp - itos.cpp path-string.cpp - round.cpp sp-svg.def stringstream.cpp strip-trailing-zeros.cpp diff --git a/src/text-context.cpp b/src/text-context.cpp index 502973633..f12ce6aa6 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")); } @@ -1389,8 +1390,11 @@ SPCSSAttr *sp_text_get_style_at_cursor(SPEventContext const *ec) return NULL; SPObject const *obj = sp_te_object_at_position(tc->text, tc->text_sel_end); - if (obj) - return take_style_from_item(SP_ITEM(obj)); + + if (obj) { + return take_style_from_item(const_cast<SPObject*>(obj)); + } + return NULL; } diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index e2cda6247..cb83541e3 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -213,7 +213,7 @@ Glib::RefPtr<Gdk::Pixbuf> Tracer::sioxProcessImage(SPImage *img, Glib::RefPtr<Gd SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (!desktop) { - g_warning(_("Trace: No active desktop")); + g_warning("%s", _("Trace: No active desktop")); return Glib::RefPtr<Gdk::Pixbuf>(NULL); } @@ -310,7 +310,7 @@ Glib::RefPtr<Gdk::Pixbuf> Tracer::sioxProcessImage(SPImage *img, Glib::RefPtr<Gd SioxImage result = sengine.extractForeground(simage, 0xffffff); if (!result.isValid()) { - g_warning(_("Invalid SIOX result")); + g_warning("%s", _("Invalid SIOX result")); return Glib::RefPtr<Gdk::Pixbuf>(NULL); } diff --git a/src/tweak-context.cpp b/src/tweak-context.cpp index 2171ecbe4..65106e651 100644 --- a/src/tweak-context.cpp +++ b/src/tweak-context.cpp @@ -168,7 +168,7 @@ void SPTweakContext::update_cursor (bool with_shift) { num = g_slist_length(const_cast<GSList *>(desktop->selection->itemList())); sel_message = g_strdup_printf(ngettext("<b>%i</b> object selected","<b>%i</b> objects selected",num), num); } else { - sel_message = g_strdup_printf(_("<b>Nothing</b> selected")); + sel_message = g_strdup_printf("%s", _("<b>Nothing</b> selected")); } switch (this->mode) { diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 233e01862..24324c874 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -175,6 +175,7 @@ set(ui_SRC dialog/object-properties.h dialog/ocaldialogs.h dialog/panel-dialog.h + dialog/pixelartdialog.h dialog/print-colors-preview-dialog.h dialog/print.h @@ -183,7 +184,7 @@ set(ui_SRC dialog/swatches.h dialog/symbols.h dialog/template-load-tab.h - dialog/template-widget.h + dialog/template-widget.h dialog/text-edit.h dialog/tile.h dialog/tracedialog.h 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..37d0ce213 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,23 @@ 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 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"; + } else if (doc_w_unit == "%" && sp_desktop_document(dt)->getRoot()->viewBox_set) { + doc_w_unit = "px"; + doc_w = sp_desktop_document(dt)->getRoot()->viewBox.width(); + } + double 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"; + } else if (doc_h_unit == "%" && sp_desktop_document(dt)->getRoot()->viewBox_set) { + doc_h_unit = "px"; + doc_h = sp_desktop_document(dt)->getRoot()->viewBox.height(); + } + _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 +1639,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/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index 3feed2afe..b9e5d4883 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -3,7 +3,7 @@ * Dialog for renaming layers. */ /* Author: - * Bryce W. Harrington <bryce@bryceharrington.com> + * Bryce W. Harrington <bryce@bryceharrington.org> * Andrius R. <knutux@gmail.com> * Abhishek Sharma * diff --git a/src/ui/dialog/layer-properties.h b/src/ui/dialog/layer-properties.h index d38b8edf5..d114c6ba5 100644 --- a/src/ui/dialog/layer-properties.h +++ b/src/ui/dialog/layer-properties.h @@ -2,7 +2,7 @@ * @brief Dialog for renaming layers */ /* Author: - * Bryce W. Harrington <bryce@bryceharrington.com> + * Bryce W. Harrington <bryce@bryceharrington.org> * * Copyright (C) 2004 Bryce Harrington * diff --git a/src/ui/dialog/pixelartdialog.cpp b/src/ui/dialog/pixelartdialog.cpp index ef181b357..ff527434e 100644 --- a/src/ui/dialog/pixelartdialog.cpp +++ b/src/ui/dialog/pixelartdialog.cpp @@ -16,13 +16,10 @@ # include <config.h> #endif -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include "pixelartdialog.h" #include <gtkmm/radiobutton.h> #include <gtkmm/stock.h> +#include <gtkmm/messagedialog.h> #include <gtk/gtk.h> //for GTK_RESPONSE* types #include <glibmm/i18n.h> @@ -132,7 +129,9 @@ private: Gtk::RadioButton voronoiRadioButton; Gtk::RadioButton noOptimizeRadioButton; +#if LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH Gtk::RadioButton optimizeRadioButton; +#endif // LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH SPDesktop *desktop; DesktopTracker deskTrack; @@ -250,12 +249,14 @@ PixelArtDialogImpl::PixelArtDialogImpl() : outputVBox.pack_start(noOptimizeRadioButton, false, false); +#if LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH optimizeRadioButton.set_label(_("_Smooth curves")); optimizeRadioButton.set_tooltip_text(_("The Kopf-Lischinski algorithm")); optimizeRadioButton.set_use_underline(true); optimizeRadioButton.set_group(outputGroup); outputVBox.pack_start(optimizeRadioButton, false, false); +#endif // LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH outputFrame.set_label(_("Output")); outputFrame.add(outputVBox); @@ -311,7 +312,11 @@ Tracer::Kopf2011::Options PixelArtDialogImpl::options() options.islandsWeight = islandsWeightSpinner.get_value_as_int(); options.sparsePixelsMultiplier = sparsePixelsMultiplierSpinner.get_value(); options.sparsePixelsRadius = sparsePixelsRadiusSpinner.get_value_as_int(); +#if LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH options.optimize = optimizeRadioButton.get_active(); +#else // LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH + options.optimize = false; +#endif // LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH options.nthreads = Inkscape::Preferences::get() ->getIntLimited("/options/threading/numthreads", @@ -367,6 +372,17 @@ void PixelArtDialogImpl::processLibdepixelize(SPImage *img) Glib::RefPtr<Gdk::Pixbuf> pixbuf = Glib::wrap(img->pixbuf->getPixbufRaw(), true); + if ( pixbuf->get_width() > 256 || pixbuf->get_height() > 256 ) { + char *msg = _("Image looks too big. Process may take a while and is" + " wise to save your document before continue." + "\n\nContinue the procedure (without saving)?"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_WARNING, + Gtk::BUTTONS_OK_CANCEL, true); + + if ( dialog.run() != Gtk::RESPONSE_OK ) + return; + } + if ( voronoiRadioButton.get_active() ) { out = Tracer::Kopf2011::to_voronoi(pixbuf, options()); } else { @@ -442,7 +458,11 @@ void PixelArtDialogImpl::setDefaults() sparsePixelsMultiplierSpinner.set_value(Tracer::Kopf2011::Options ::SPARSE_PIXELS_MULTIPLIER); +#if LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH optimizeRadioButton.set_active(); +#else // LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH + noOptimizeRadioButton.set_active(); +#endif // LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH ignorePreview = false; diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 4c8c77f96..03ac9dc64 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: @@ -101,7 +101,7 @@ static void draw_page( unlink (tmp_png.c_str()); } else { - g_warning(_("Could not open temporary PNG for bitmap printing")); + g_warning("%s", _("Could not open temporary PNG for bitmap printing")); } } else { @@ -144,11 +144,11 @@ static void draw_page( ret = ctx->finish(); } else { - g_warning(_("Could not set up Document")); + g_warning("%s", _("Could not set up Document")); } } else { - g_warning(_("Failed to set CairoRenderContext")); + g_warning("%s", _("Failed to set CairoRenderContext")); } // Clean up @@ -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/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index 9cc18c02c..45106755c 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -459,7 +459,7 @@ SpellCheck::finished () if (_stops) label = g_strdup_printf(_("<b>Finished</b>, <b>%d</b> words added to dictionary"), _adds); else - label = g_strdup_printf(_("<b>Finished</b>, nothing suspicious found")); + label = g_strdup_printf("%s", _("<b>Finished</b>, nothing suspicious found")); banner_label.set_markup(label); g_free(label); } diff --git a/src/ui/dialog/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp index 265ee8026..8e33cf503 100644 --- a/src/ui/dialog/template-load-tab.cpp +++ b/src/ui/dialog/template-load-tab.cpp @@ -18,12 +18,16 @@ #include <glibmm/fileutils.h> #include <glibmm/miscutils.h> #include <glibmm/stringutils.h> +#include <iostream> +#include <list> +#include "extension/db.h" +#include "extension/effect.h" +#include "inkscape.h" #include "interface.h" #include "file.h" #include "path-prefix.h" #include "preferences.h" -#include "inkscape.h" #include "xml/repr.h" #include "xml/document.h" #include "xml/node.h" @@ -152,7 +156,7 @@ void TemplateLoadTab::_refreshTemplatesList() case LIST_KEYWORD: { for (std::map<Glib::ustring, TemplateData>::iterator it = _tdata.begin() ; it != _tdata.end() ; ++it) { - if (it->second.keywords.count(_current_keyword) != 0){ + if (it->second.keywords.count(_current_keyword.lowercase()) != 0){ Gtk::TreeModel::iterator iter = _tlist_store->append(); Gtk::TreeModel::Row row = *iter; row[_columns.textValue] = it->first; @@ -163,11 +167,11 @@ void TemplateLoadTab::_refreshTemplatesList() case USER_SPECIFIED : { for (std::map<Glib::ustring, TemplateData>::iterator it = _tdata.begin() ; it != _tdata.end() ; ++it) { - if (it->second.keywords.count(_current_keyword) != 0 || - it->second.display_name.find(_current_keyword) != Glib::ustring::npos || - it->second.author.find(_current_keyword) != Glib::ustring::npos || - it->second.short_description.find(_current_keyword) != Glib::ustring::npos || - it->second.long_description.find(_current_keyword) != Glib::ustring::npos ) + if (it->second.keywords.count(_current_keyword.lowercase()) != 0 || + it->second.display_name.lowercase().find(_current_keyword.lowercase()) != Glib::ustring::npos || + it->second.author.lowercase().find(_current_keyword.lowercase()) != Glib::ustring::npos || + it->second.short_description.lowercase().find(_current_keyword.lowercase()) != Glib::ustring::npos || + it->second.long_description.lowercase().find(_current_keyword.lowercase()) != Glib::ustring::npos ) { Gtk::TreeModel::iterator iter = _tlist_store->append(); Gtk::TreeModel::Row row = *iter; @@ -187,10 +191,13 @@ void TemplateLoadTab::_loadTemplates() // system templates dir _getTemplatesFromDir(INKSCAPE_TEMPLATESDIR + _loading_path); + + // procedural templates + _getProceduralTemplates(); } -TemplateLoadTab::TemplateData TemplateLoadTab::_processTemplateFile(const Glib::ustring &path) +TemplateLoadTab::TemplateData TemplateLoadTab::_processTemplateFile(const std::string &path) { TemplateData result; result.path = path; @@ -209,7 +216,6 @@ TemplateLoadTab::TemplateData TemplateLoadTab::_processTemplateFile(const Glib:: Inkscape::XML::Document *rdoc; rdoc = sp_repr_read_file(path.data(), SP_SVG_NS_URI); Inkscape::XML::Node *myRoot; - Inkscape::XML::Node *dataNode; if (rdoc){ myRoot = rdoc->root(); @@ -221,44 +227,14 @@ TemplateLoadTab::TemplateData TemplateLoadTab::_processTemplateFile(const Glib:: if (myRoot == NULL) // No template info return result; - - if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:_name")) != NULL) - result.display_name = dgettext("Document template name", dataNode->firstChild()->content()); - if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:author")) != NULL) - result.author = dataNode->firstChild()->content(); - if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:_short")) != NULL) - result.short_description = dgettext("Document template short description", dataNode->firstChild()->content()); - if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:_long") )!= NULL) - result.long_description = dgettext("Document template long description", dataNode->firstChild()->content()); - if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:preview")) != NULL) - result.preview_name = dataNode->firstChild()->content(); - if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:date")) != NULL){ - result.creation_date = dataNode->firstChild()->content(); - } - - if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:_keywords")) != NULL){ - Glib::ustring data = dataNode->firstChild()->content(); - while (!data.empty()){ - std::size_t pos = data.find_first_of(" "); - if (pos == Glib::ustring::npos) - pos = data.size(); - - Glib::ustring keyword = dgettext("Document template keyword", data.substr(0, pos).data()); - result.keywords.insert(keyword); - _keywords.insert(keyword); - - if (pos == data.size()) - break; - data.erase(0, pos+1); - } - } + _getDataFromNode(myRoot, result); } return result; } -void TemplateLoadTab::_getTemplatesFromDir(const Glib::ustring &path) +void TemplateLoadTab::_getTemplatesFromDir(const std::string &path) { if ( !Glib::file_test(path, Glib::FILE_TEST_EXISTS) || !Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) @@ -266,9 +242,9 @@ void TemplateLoadTab::_getTemplatesFromDir(const Glib::ustring &path) Glib::Dir dir(path); - Glib::ustring file = Glib::build_filename(path, dir.read_name()); + std::string file = Glib::build_filename(path, dir.read_name()); while (file != path){ - if (Glib::str_has_suffix(file, ".svg") && !Glib::str_has_prefix(Glib::path_get_basename(file), "default")){ + if (Glib::str_has_suffix(file, ".svg") && !Glib::str_has_prefix(Glib::path_get_basename(file), "default.")){ TemplateData tmp = _processTemplateFile(file); if (tmp.display_name != "") _tdata[tmp.display_name] = tmp; @@ -277,5 +253,66 @@ void TemplateLoadTab::_getTemplatesFromDir(const Glib::ustring &path) } } + +void TemplateLoadTab::_getProceduralTemplates() +{ + std::list<Inkscape::Extension::Effect *> effects; + Inkscape::Extension::db.get_effect_list(effects); + + std::list<Inkscape::Extension::Effect *>::iterator it = effects.begin(); + while (it != effects.end()){ + Inkscape::XML::Node *myRoot; + myRoot = (*it)->get_repr(); + myRoot = sp_repr_lookup_name(myRoot, "inkscape:_templateinfo"); + + if (myRoot){ + TemplateData result; + result.display_name = (*it)->get_name(); + result.is_procedural = true; + result.path = ""; + result.tpl_effect = *it; + + _getDataFromNode(myRoot, result); + _tdata[result.display_name] = result; + } + ++it; + } +} + + +void TemplateLoadTab::_getDataFromNode(Inkscape::XML::Node *dataNode, TemplateData &data) +{ + Inkscape::XML::Node *currentData; + if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:_name")) != NULL) + data.display_name = dgettext("Document template name", currentData->firstChild()->content()); + if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:author")) != NULL) + data.author = currentData->firstChild()->content(); + if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:_shortdesc")) != NULL) + data.short_description = dgettext("Document template short description", currentData->firstChild()->content()); + if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:_long") )!= NULL) + data.long_description = dgettext("Document template long description", currentData->firstChild()->content()); + if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:preview")) != NULL) + data.preview_name = currentData->firstChild()->content(); + if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:date")) != NULL) + data.creation_date = currentData->firstChild()->content(); + + if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:_keywords")) != NULL){ + Glib::ustring tplKeywords = currentData->firstChild()->content(); + while (!tplKeywords.empty()){ + std::size_t pos = tplKeywords.find_first_of(" "); + if (pos == Glib::ustring::npos) + pos = tplKeywords.size(); + + Glib::ustring keyword = dgettext("Document template keyword", tplKeywords.substr(0, pos).data()); + data.keywords.insert(keyword.lowercase()); + _keywords.insert(keyword.lowercase()); + + if (pos == tplKeywords.size()) + break; + tplKeywords.erase(0, pos+1); + } + } +} + } } diff --git a/src/ui/dialog/template-load-tab.h b/src/ui/dialog/template-load-tab.h index 50f3e0be2..744a2a9fb 100644 --- a/src/ui/dialog/template-load-tab.h +++ b/src/ui/dialog/template-load-tab.h @@ -18,6 +18,10 @@ #include <gtkmm/treeview.h> #include <map> #include <set> +#include <string> + +#include "xml/node.h" +#include "extension/effect.h" namespace Inkscape { @@ -32,7 +36,7 @@ public: struct TemplateData { bool is_procedural; - Glib::ustring path; + std::string path; Glib::ustring display_name; Glib::ustring author; Glib::ustring short_description; @@ -40,6 +44,7 @@ public: Glib::ustring preview_name; Glib::ustring creation_date; std::set<Glib::ustring> keywords; + Inkscape::Extension::Effect *tpl_effect; }; TemplateLoadTab(); @@ -60,7 +65,7 @@ protected: Glib::ustring _current_keyword; Glib::ustring _current_template; - Glib::ustring _loading_path; + std::string _loading_path; std::map<Glib::ustring, TemplateData> _tdata; std::set<Glib::ustring> _keywords; @@ -91,9 +96,11 @@ private: SearchType _current_search_type; - void _getTemplatesFromDir(const Glib::ustring &); + void _getDataFromNode(Inkscape::XML::Node *, TemplateData &); + void _getProceduralTemplates(); + void _getTemplatesFromDir(const std::string &); void _keywordSelected(); - TemplateData _processTemplateFile(const Glib::ustring &); + TemplateData _processTemplateFile(const std::string &); }; } diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index be7e2b515..7e34e5a58 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -19,7 +19,14 @@ #include <glibmm/miscutils.h> #include "template-load-tab.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "document.h" +#include "document-undo.h" #include "file.h" +#include "extension/implementation/implementation.h" +#include "inkscape.h" + namespace Inkscape { namespace UI { @@ -28,18 +35,16 @@ namespace UI { TemplateWidget::TemplateWidget() : _more_info_button(_("More info")) , _short_description_label(_(" ")) - , _template_author_label(_(" ")) , _template_name_label(_("no template selected")) + , _effect_prefs(NULL) { pack_start(_template_name_label, Gtk::PACK_SHRINK, 10); - pack_start(_template_author_label, Gtk::PACK_SHRINK, 0); pack_start(_preview_box, Gtk::PACK_SHRINK, 0); _preview_box.pack_start(_preview_image, Gtk::PACK_EXPAND_PADDING, 15); _preview_box.pack_start(_preview_render, Gtk::PACK_EXPAND_PADDING, 10); _short_description_label.set_line_wrap(true); - //_short_description_label.set_size_request(200); Gtk::Alignment *align; align = manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); @@ -55,10 +60,19 @@ TemplateWidget::TemplateWidget() void TemplateWidget::create() { - if (_current_template.path == "") + if (_current_template.display_name == "") return; - if (_current_template.is_procedural) {} + if (_current_template.is_procedural){ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDesktop *desc = sp_file_new_default(); + _current_template.tpl_effect->effect(desc); + DocumentUndo::clearUndo(sp_desktop_document(desc)); + sp_desktop_document(desc)->setModifiedSinceSave(false); + + if (desktop) + desktop->clearWaitingCursor(); + } else { sp_file_new(_current_template.path); } @@ -68,34 +82,41 @@ void TemplateWidget::create() void TemplateWidget::display(TemplateLoadTab::TemplateData data) { _current_template = data; - if (data.is_procedural){} - else{ - _template_name_label.set_text(_current_template.display_name); - _template_author_label.set_text(_current_template.author); - _short_description_label.set_text(_current_template.short_description); + + _template_name_label.set_text(_current_template.display_name); + _short_description_label.set_text(_current_template.short_description); - Glib::ustring imagePath = Glib::build_filename(Glib::path_get_dirname(_current_template.path), _current_template.preview_name); - if (data.preview_name != ""){ - _preview_image.set(imagePath); - _preview_image.show(); - _preview_render.hide(); - } - else{ - _preview_render.showImage(data.path); - _preview_render.show(); - _preview_image.hide(); - } + _preview_render.hide(); + _preview_image.hide(); + + std::string imagePath = Glib::build_filename(Glib::path_get_dirname(_current_template.path), _current_template.preview_name); + if (data.preview_name != ""){ + _preview_image.set(imagePath); + _preview_image.show(); + } + else if (!data.is_procedural){ + Glib::ustring gPath = data.path.c_str(); + _preview_render.showImage(gPath); + _preview_render.show(); + } + + if (_effect_prefs != NULL){ + remove (*_effect_prefs); + _effect_prefs = NULL; + } + if (data.is_procedural){ + _effect_prefs = data.tpl_effect->get_imp()->prefs_effect(data.tpl_effect, SP_ACTIVE_DESKTOP, NULL, NULL); + pack_start(*_effect_prefs); } } void TemplateWidget::_displayTemplateDetails() { - if (_current_template.path == "") - return; + Glib::ustring message = _current_template.display_name + "\n\n"; - Glib::ustring message = _current_template.display_name + "\n\n" + - _("Path: ") + _current_template.path + "\n\n"; + if (_current_template.path != "") + message += _("Path: ") + _current_template.path + "\n\n"; if (_current_template.long_description != "") message += _("Description: ") + _current_template.long_description + "\n\n"; diff --git a/src/ui/dialog/template-widget.h b/src/ui/dialog/template-widget.h index f7e1267ce..bb35d26a0 100644 --- a/src/ui/dialog/template-widget.h +++ b/src/ui/dialog/template-widget.h @@ -17,6 +17,7 @@ #include "template-load-tab.h" + namespace Inkscape { namespace UI { @@ -36,8 +37,8 @@ private: Gtk::Image _preview_image; Dialog::SVGPreview _preview_render; Gtk::Label _short_description_label; - Gtk::Label _template_author_label; Gtk::Label _template_name_label; + Gtk::Widget *_effect_prefs; void _displayTemplateDetails(); }; 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..2379dc181 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) { @@ -473,14 +474,16 @@ PageSizer::setDim (double w, double h, bool changeList) _changedw_connection.block(); _changedh_connection.block(); + _unit = w.unit->abbr; + 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 +506,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 +551,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 +566,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 +647,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 +658,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 +674,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 +690,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 +704,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..1114ff32b 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; @@ -57,7 +65,7 @@ int SpinButton::on_input(double* newvalue) bool SpinButton::on_my_focus_in_event(GdkEventFocus* /*event*/) { - on_focus_in_value = get_value(); + _on_focus_in_value = get_value(); return false; // do not consume the event } @@ -84,7 +92,7 @@ bool SpinButton::on_my_key_press_event(GdkEventKey* event) void SpinButton::undo() { - set_value(on_focus_in_value); + set_value(_on_focus_in_value); } diff --git a/src/ui/widget/spinbutton.h b/src/ui/widget/spinbutton.h index fe5d699e7..812b5f515 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), @@ -37,7 +38,9 @@ class SpinButton : public Gtk::SpinButton public: SpinButton(double climb_rate = 0.0, guint digits = 0) : Gtk::SpinButton(climb_rate, digits), - _unit_menu(NULL) + _unit_menu(NULL), + _unit_tracker(NULL), + _on_focus_in_value(0.) { connect_signals(); }; @@ -47,7 +50,9 @@ public: explicit SpinButton(Gtk::Adjustment& adjustment, double climb_rate = 0.0, guint digits = 0) #endif : Gtk::SpinButton(adjustment, climb_rate, digits), - _unit_menu(NULL) + _unit_menu(NULL), + _unit_tracker(NULL), + _on_focus_in_value(0.) { connect_signals(); }; @@ -55,9 +60,13 @@ public: 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. + double _on_focus_in_value; void connect_signals(); @@ -90,8 +99,6 @@ protected: */ void undo(); - double on_focus_in_value; - private: // noncopyable SpinButton(const SpinButton&); 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..59717d0b5 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 { @@ -290,6 +321,9 @@ bool UnitTable::load(std::string const &filename) { Glib::ustring unitfile = Glib::file_get_contents(filename); ctx.parse(unitfile); ctx.end_parse(); + } catch (Glib::FileError const &e) { + g_warning("Units file %s is missing: %s\n", filename.c_str(), e.what().c_str()); + return false; } catch (Glib::MarkupError const &e) { g_warning("Problem loading units file '%s': %s\n", filename.c_str(), e.what().c_str()); return false; @@ -421,6 +455,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..f7d2b2bd5 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -286,7 +286,7 @@ void gr_read_selection( Inkscape::Selection *selection, } } if (spread != spr_selected) { - if (spr_selected != INT_MAX) { + if (spr_selected != SP_GRADIENT_SPREAD_UNDEFINED) { spr_multi = true; } else { spr_selected = spread; @@ -319,7 +319,7 @@ void gr_read_selection( Inkscape::Selection *selection, } } if (spread != spr_selected) { - if (spr_selected != INT_MAX) { + if (spr_selected != SP_GRADIENT_SPREAD_UNDEFINED) { spr_multi = true; } else { spr_selected = spread; @@ -345,7 +345,7 @@ void gr_read_selection( Inkscape::Selection *selection, } } if (spread != spr_selected) { - if (spr_selected != INT_MAX) { + if (spr_selected != SP_GRADIENT_SPREAD_UNDEFINED) { spr_multi = true; } else { spr_selected = spread; @@ -380,7 +380,7 @@ static void gr_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointe } SPGradient *gr_selected = 0; - SPGradientSpread spr_selected = static_cast<SPGradientSpread>(INT_MAX); // meaning undefined + SPGradientSpread spr_selected = SP_GRADIENT_SPREAD_UNDEFINED; bool gr_multi = false; bool spr_multi = false; @@ -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/spw-utilities.cpp b/src/widgets/spw-utilities.cpp index d0a3ed1c5..9c0c8d7c6 100644 --- a/src/widgets/spw-utilities.cpp +++ b/src/widgets/spw-utilities.cpp @@ -2,7 +2,7 @@ * Inkscape Widget Utilities * * Authors: - * Bryce W. Harrington <brycehar@bryceharrington.com> + * Bryce W. Harrington <brycehar@bryceharrington.org> * bulia byak <buliabyak@users.sf.net> * * Copyright (C) 2003 Bryce W. Harrington diff --git a/src/widgets/spw-utilities.h b/src/widgets/spw-utilities.h index d52cbd888..31f29e026 100644 --- a/src/widgets/spw-utilities.h +++ b/src/widgets/spw-utilities.h @@ -5,7 +5,7 @@ * Inkscape Widget Utilities * * Author: - * Bryce W. Harrington <brycehar@bryceharrington.com> + * Bryce W. Harrington <brycehar@bryceharrington.org> * * Copyright (C) 2003 Bryce Harrington * 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) { diff --git a/src/xml/quote-test.h b/src/xml/quote-test.h index bd5c1f54c..bc01ec4e9 100644 --- a/src/xml/quote-test.h +++ b/src/xml/quote-test.h @@ -7,10 +7,7 @@ #include <cstring> #include <functional> -/* mental disclaims all responsibility for this evil idea for testing - static functions. The main disadvantages are that we retain any - #define's and `using' directives of the included file. */ -#include "quote.cpp" +#include "quote.h" class XmlQuoteTest : public CxxTest::TestSuite { diff --git a/src/xml/quote.cpp b/src/xml/quote.cpp index 030a6c764..c9e001d05 100644 --- a/src/xml/quote.cpp +++ b/src/xml/quote.cpp @@ -19,7 +19,7 @@ /** \return strlen(xml_quote_strdup(\a val)) (without doing the malloc). * \pre val != NULL */ -static size_t +size_t xml_quoted_strlen(char const *val) { size_t ret = 0; @@ -43,11 +43,11 @@ xml_quoted_strlen(char const *val) static void xml_quote(char *dest, char const *src) { -#define COPY_LIT(_lit) do { \ - size_t cpylen = sizeof(_lit "") - 1; \ - memcpy(dest, _lit, cpylen); \ - dest += cpylen; \ - } while(0) +#define COPY_LIT(_lit) do { \ + size_t cpylen = sizeof(_lit "") - 1; \ + memcpy(dest, _lit, cpylen); \ + dest += cpylen; \ + } while(0) for (; *src != '\0'; ++src) { switch (*src) { diff --git a/src/xml/quote.h b/src/xml/quote.h index 597272cd3..8e3bca0eb 100644 --- a/src/xml/quote.h +++ b/src/xml/quote.h @@ -1,6 +1,9 @@ #ifndef SEEN_XML_QUOTE_H #define SEEN_XML_QUOTE_H +#include <stddef.h> + +size_t xml_quoted_strlen(char const *val); char *xml_quote_strdup(char const *src); diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index 8c8425de0..12280ea5a 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -432,13 +432,11 @@ unsigned int sp_repr_get_int(Inkscape::XML::Node *repr, gchar const *key, int *v unsigned int sp_repr_get_double(Inkscape::XML::Node *repr, gchar const *key, double *val) { - gchar const *v; - g_return_val_if_fail(repr != NULL, FALSE); g_return_val_if_fail(key != NULL, FALSE); g_return_val_if_fail(val != NULL, FALSE); - v = repr->attribute(key); + gchar const *v = repr->attribute(key); if (v != NULL) { *val = g_ascii_strtod(v, NULL); |
