diff options
Diffstat (limited to 'src')
37 files changed, 1655 insertions, 1249 deletions
diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index dfccb63bf..3058eab2d 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -4,6 +4,7 @@ * Authors: * Maximilian Albert <Anhalter42@gmx.de> * Abhishek Sharma + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2007 Authors * @@ -166,13 +167,12 @@ void Box3DSide::set_shape() { SPObject *parent = this->parent; - if (!SP_IS_BOX3D(parent)) { + SPBox3D *box = dynamic_cast<SPBox3D *>(parent); + if (!box) { g_warning("Parent of 3D box side is not a 3D box.\n"); return; } - SPBox3D *box = SP_BOX3D(parent); - Persp3D *persp = box3d_side_perspective(this); if (!persp) { @@ -259,7 +259,8 @@ box3d_side_compute_corner_ids(Box3DSide *side, unsigned int corners[4]) { Persp3D * box3d_side_perspective(Box3DSide *side) { - return SP_BOX3D(side->parent)->persp_ref->getObject(); + SPBox3D *box = side ? dynamic_cast<SPBox3D *>(side->parent) : NULL; + return box ? box->persp_ref->getObject() : NULL; } Inkscape::XML::Node *box3d_side_convert_to_path(Box3DSide *side) { diff --git a/src/box3d.cpp b/src/box3d.cpp index f872081b8..93622be4c 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -66,27 +66,23 @@ SPBox3D::~SPBox3D() { } void SPBox3D::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPBox3D* object = this; - SPGroup::build(document, repr); - SPBox3D *box = SP_BOX3D (object); - box->my_counter = counter++; + my_counter = counter++; /* we initialize the z-orders to zero so that they are updated during dragging */ for (int i = 0; i < 6; ++i) { - box->z_orders[i] = 0; + z_orders[i] = 0; } // TODO: Create/link to the correct perspective - SPDocument *doc = box->document; - if ( doc ) { - box->persp_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(box3d_ref_changed), box)); + if ( document ) { + persp_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(box3d_ref_changed), this)); - object->readAttr( "inkscape:perspectiveID" ); - object->readAttr( "inkscape:corner0" ); - object->readAttr( "inkscape:corner7" ); + readAttr( "inkscape:perspectiveID" ); + readAttr( "inkscape:corner0" ); + readAttr( "inkscape:corner7" ); } } @@ -188,11 +184,15 @@ box3d_ref_changed(SPObject *old_ref, SPObject *ref, SPBox3D *box) { if (old_ref) { sp_signal_disconnect_by_data(old_ref, box); - persp3d_remove_box (SP_PERSP3D(old_ref), box); + Persp3D *oldPersp = dynamic_cast<Persp3D *>(old_ref); + if (oldPersp) { + persp3d_remove_box(oldPersp, box); + } } - if ( SP_IS_PERSP3D(ref) && ref != box ) // FIXME: Comparisons sane? + Persp3D *persp = dynamic_cast<Persp3D *>(ref); + if ( persp && (ref != box) ) // FIXME: Comparisons sane? { - persp3d_add_box (SP_PERSP3D(ref), box); + persp3d_add_box(persp, box); } } @@ -273,9 +273,6 @@ void box3d_position_set(SPBox3D *box) } Geom::Affine SPBox3D::set_transform(Geom::Affine const &xform) { - SPBox3D* item = this; - SPBox3D *box = item; - // We don't apply the transform to the box directly but instead to its perspective (which is // done in sp_selection_apply_affine). Here we only adjust strokes, patterns, etc. @@ -283,10 +280,9 @@ Geom::Affine SPBox3D::set_transform(Geom::Affine const &xform) { gdouble const sw = hypot(ret[0], ret[1]); gdouble const sh = hypot(ret[2], ret[3]); - for ( SPObject *child = box->firstChild(); child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - SPItem *childitem = SP_ITEM(child); - + for ( SPObject *child = firstChild(); child; child = child->getNext() ) { + SPItem *childitem = dynamic_cast<SPItem *>(child); + if (childitem) { // Adjust stroke width childitem->adjust_stroke(sqrt(fabs(sw * sh))); @@ -1220,9 +1216,10 @@ box3d_check_for_swapped_coords(SPBox3D *box) { } static void box3d_extract_boxes_rec(SPObject *obj, std::list<SPBox3D *> &boxes) { - if (SP_IS_BOX3D(obj)) { - boxes.push_back(SP_BOX3D(obj)); - } else if (SP_IS_GROUP(obj)) { + SPBox3D *box = dynamic_cast<SPBox3D *>(obj); + if (box) { + boxes.push_back(box); + } else if (dynamic_cast<SPGroup *>(obj)) { for ( SPObject *child = obj->firstChild(); child; child = child->getNext() ) { box3d_extract_boxes_rec(child, boxes); } @@ -1306,7 +1303,9 @@ SPGroup *box3d_convert_to_group(SPBox3D *box) grepr->setAttribute("id", id); - return SP_GROUP(doc->getObjectByRepr(grepr)); + SPGroup *group = dynamic_cast<SPGroup *>(doc->getObjectByRepr(grepr)); + g_assert(group != NULL); + return group; } const char *SPBox3D::displayName() const { diff --git a/src/box3d.h b/src/box3d.h index 60b966187..85f481e5b 100644 --- a/src/box3d.h +++ b/src/box3d.h @@ -8,6 +8,7 @@ * Lauris Kaplinski <lauris@kaplinski.com> * Maximilian Albert <Anhalter42@gmx.de> * Abhishek Sharma + * Jon A. Cruz <jon@joncruz.org. * * Copyright (C) 2007 Authors * Copyright (C) 1999-2002 Lauris Kaplinski @@ -21,8 +22,6 @@ #include "axis-manip.h" #define SP_TYPE_BOX3D (box3d_get_type ()) -#define SP_BOX3D(obj) (dynamic_cast<SPBox3D*>((SPObject*)obj)) -#define SP_IS_BOX3D(obj) (dynamic_cast<const SPBox3D*>((SPObject*)obj) != NULL) class Persp3D; class Persp3DReference; diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 9bb81cea5..8ed74b550 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -870,10 +870,9 @@ DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) { // Sometimes there's no BBOX in state, reason unknown (bug 992817) // I made this not an assert to remove the warning - // This warning clutters the console output, so commented out if (!(_state & STATE_BBOX) || !(_state & STATE_PICK)) { - /*g_warning("Invalid state when picking: STATE_BBOX = %d, STATE_PICK = %d", - _state & STATE_BBOX, _state & STATE_PICK);*/ + g_warning("Invalid state when picking: STATE_BBOX = %d, STATE_PICK = %d", + _state & STATE_BBOX, _state & STATE_PICK); return NULL; } // ignore invisible and insensitive items unless sticky diff --git a/src/document.cpp b/src/document.cpp index 70fec83d7..b3d606417 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -621,7 +621,10 @@ Inkscape::Util::Quantity SPDocument::getWidth() const void SPDocument::setWidth(const Inkscape::Util::Quantity &width) { - gdouble old_computed = root->width.computed; + Inkscape::Util::Unit const *old_units = unit_table.getUnit("px"); + if (root->width.unit) + old_units = unit_table.getUnit(root->width.unit); + gdouble old_converted = Inkscape::Util::Quantity::convert(root->width.value, old_units, width.unit); root->width.computed = width.value("px"); /* SVG does not support meters as a unit, so we must translate meters to * cm when writing */ @@ -634,7 +637,7 @@ void SPDocument::setWidth(const Inkscape::Util::Quantity &width) } if (root->viewBox_set) - root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.computed / old_computed) * root->viewBox.width(), root->viewBox.bottom())); + root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.value / old_converted) * root->viewBox.width(), root->viewBox.bottom())); root->updateRepr(); } @@ -659,7 +662,10 @@ Inkscape::Util::Quantity SPDocument::getHeight() const void SPDocument::setHeight(const Inkscape::Util::Quantity &height) { - gdouble old_computed = root->height.computed; + Inkscape::Util::Unit const *old_units = unit_table.getUnit("px"); + if (root->height.unit) + old_units = unit_table.getUnit(root->height.unit); + gdouble old_converted = Inkscape::Util::Quantity::convert(root->height.value, old_units, height.unit); root->height.computed = height.value("px"); /* SVG does not support meters as a unit, so we must translate meters to * cm when writing */ @@ -672,7 +678,7 @@ void SPDocument::setHeight(const Inkscape::Util::Quantity &height) } if (root->viewBox_set) - root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.computed / old_computed) * root->viewBox.height())); + root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.value / old_converted) * root->viewBox.height())); root->updateRepr(); } diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 7e61cdbbb..cb414b3b2 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -1132,8 +1132,8 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver cairo_pattern_t* CairoRenderContext::_createHatchPainter(SPPaintServer const *const paintserver, Geom::OptRect const &pbox) { - g_assert( SP_IS_HATCH(paintserver) ); - SPHatch *hatch = SP_HATCH(paintserver); + SPHatch const *hatch = dynamic_cast<SPHatch const *>(paintserver); + g_assert( hatch ); g_assert(hatch->pitch() > 0); @@ -1141,7 +1141,9 @@ CairoRenderContext::_createHatchPainter(SPPaintServer const *const paintserver, Inkscape::Drawing drawing; unsigned dkey = SPItem::display_key_new(1); - hatch->show(drawing, dkey, pbox); + // TODO need to refactor 'evil' referenced code for const correctness. + SPHatch *evil = const_cast<SPHatch *>(hatch); + evil->show(drawing, dkey, pbox); SPHatch::RenderInfo render_info = hatch->calculateRenderInfo(dkey); Geom::Rect tile_rect = render_info.tile_rect; @@ -1177,8 +1179,7 @@ CairoRenderContext::_createHatchPainter(SPPaintServer const *const paintserver, pattern_ctx->transform(Geom::Translate(-overflow_right_strip, 0.0)); pattern_ctx->pushState(); - std::vector<SPHatchPath *> children; - hatch->hatchPaths(children); + std::vector<SPHatchPath *> children(evil->hatchPaths()); for (int i = 0; i < overflow_steps; i++) { for (std::vector<SPHatchPath *>::iterator iter = children.begin(); iter != children.end(); iter++) { @@ -1200,7 +1201,7 @@ CairoRenderContext::_createHatchPainter(SPPaintServer const *const paintserver, pattern_transform = render_info.pattern_to_user_transform.inverse() * drawing_transform; ink_cairo_pattern_set_matrix(result, pattern_transform); - hatch->hide(dkey); + evil->hide(dkey); delete pattern_ctx; return result; @@ -1260,7 +1261,7 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain } } else if (SP_IS_PATTERN (paintserver)) { pattern = _createPatternPainter(paintserver, pbox); - } else if (SP_IS_HATCH (paintserver)) { + } else if ( dynamic_cast<SPHatch const *>(paintserver) ) { pattern = _createHatchPainter(paintserver, pbox); } else { return NULL; @@ -1331,8 +1332,8 @@ CairoRenderContext::_setFillStyle(SPStyle const *const style, Geom::OptRect cons if (paint_server && paint_server->isValid()) { g_assert(SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) - || SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style)) - || SP_IS_HATCH(SP_STYLE_FILL_SERVER(style))); + || SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style)) + || dynamic_cast<SPHatch *>(SP_STYLE_FILL_SERVER(style))); cairo_pattern_t *pattern = _createPatternForPaintServer(paint_server, pbox, alpha); if (pattern) { @@ -1369,7 +1370,7 @@ CairoRenderContext::_setStrokeStyle(SPStyle const *style, Geom::OptRect const &p g_assert( style->stroke.isPaintserver() || SP_IS_GRADIENT(SP_STYLE_STROKE_SERVER(style)) || SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style)) - || SP_IS_HATCH(SP_STYLE_STROKE_SERVER(style))); + || dynamic_cast<SPHatch *>(SP_STYLE_STROKE_SERVER(style))); cairo_pattern_t *pattern = _createPatternForPaintServer(SP_STYLE_STROKE_SERVER(style), pbox, alpha); diff --git a/src/inkscape-x64.rc b/src/inkscape-x64.rc index 65a2b08b9..7f4d5b9ae 100644 --- a/src/inkscape-x64.rc +++ b/src/inkscape-x64.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkscape-manifest-x64.xml" 1 VERSIONINFO - FILEVERSION 0,91,0,0 - PRODUCTVERSION 0,91,0,0 + FILEVERSION 0,91,0,9 + PRODUCTVERSION 0,91,0,9 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkscape" - VALUE "FileVersion", "0.91pre2" + VALUE "FileVersion", "0.91+devel" VALUE "InternalName", "Inkscape" VALUE "LegalCopyright", "© 2014 Inkscape" VALUE "ProductName", "Inkscape" - VALUE "ProductVersion", "0.91pre2" + VALUE "ProductVersion", "0.91+devel" END END BLOCK "VarFileInfo" diff --git a/src/inkscape.rc b/src/inkscape.rc index 689653f74..92d38f60e 100644 --- a/src/inkscape.rc +++ b/src/inkscape.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkscape-manifest.xml" 1 VERSIONINFO - FILEVERSION 0,91,0,0 - PRODUCTVERSION 0,91,0,0 + FILEVERSION 0,91,0,9 + PRODUCTVERSION 0,91,0,9 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkscape" - VALUE "FileVersion", "0.91pre2" + VALUE "FileVersion", "0.91+devel" VALUE "InternalName", "Inkscape" VALUE "LegalCopyright", "© 2014 Inkscape" VALUE "ProductName", "Inkscape" - VALUE "ProductVersion", "0.91pre2" + VALUE "ProductVersion", "0.91+devel" END END BLOCK "VarFileInfo" diff --git a/src/inkview-x64.rc b/src/inkview-x64.rc index f23fe84c9..1b7287993 100644 --- a/src/inkview-x64.rc +++ b/src/inkview-x64.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkview-manifest-x64.xml" 1 VERSIONINFO - FILEVERSION 0,91,0,0 - PRODUCTVERSION 0,91,0,0 + FILEVERSION 0,91,0,9 + PRODUCTVERSION 0,91,0,9 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkview" - VALUE "FileVersion", "0.91pre2" + VALUE "FileVersion", "0.91+devel" VALUE "InternalName", "Inkview" VALUE "LegalCopyright", "© 2014 Inkscape" VALUE "ProductName", "Inkview" - VALUE "ProductVersion", "0.91pre2" + VALUE "ProductVersion", "0.91+devel" END END BLOCK "VarFileInfo" diff --git a/src/inkview.rc b/src/inkview.rc index 43a63c725..326b0873a 100644 --- a/src/inkview.rc +++ b/src/inkview.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkview-manifest.xml" 1 VERSIONINFO - FILEVERSION 0,91,0,0 - PRODUCTVERSION 0,91,0,0 + FILEVERSION 0,91,0,9 + PRODUCTVERSION 0,91,0,9 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkview" - VALUE "FileVersion", "0.91pre2" + VALUE "FileVersion", "0.91+devel" VALUE "InternalName", "Inkview" VALUE "LegalCopyright", "© 2014 Inkscape" VALUE "ProductName", "Inkview" - VALUE "ProductVersion", "0.91pre2" + VALUE "ProductVersion", "0.91+devel" END END BLOCK "VarFileInfo" diff --git a/src/knotholder.cpp b/src/knotholder.cpp index b8d941bf7..f46daa09e 100644 --- a/src/knotholder.cpp +++ b/src/knotholder.cpp @@ -6,6 +6,7 @@ * bulia byak <buliabyak@users.sf.net> * Maximilian Albert <maximilian.albert@gmail.com> * Abhishek Sharma + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2001-2008 authors * @@ -58,8 +59,7 @@ KnotHolder::KnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFun local_change(FALSE), dragging(false) { - - if (!desktop || !item || !SP_IS_ITEM(item)) { + if (!desktop || !item) { g_print ("Error! Throw an exception, please!\n"); } @@ -128,29 +128,37 @@ KnotHolder::knot_clicked_handler(SPKnot *knot, guint state) } } - if (SP_IS_SHAPE(saved_item)) { - SP_SHAPE(saved_item)->set_shape(); + { + SPShape *savedShape = dynamic_cast<SPShape *>(saved_item); + if (savedShape) { + savedShape->set_shape(); + } } knot_holder->update_knots(); unsigned int object_verb = SP_VERB_NONE; - if (SP_IS_RECT(saved_item)) + // TODO extract duplicated blocks; + if (dynamic_cast<SPRect *>(saved_item)) { object_verb = SP_VERB_CONTEXT_RECT; - else if (SP_IS_BOX3D(saved_item)) + } else if (dynamic_cast<SPBox3D *>(saved_item)) { object_verb = SP_VERB_CONTEXT_3DBOX; - else if (SP_IS_GENERICELLIPSE(saved_item)) + } else if (dynamic_cast<SPGenericEllipse *>(saved_item)) { object_verb = SP_VERB_CONTEXT_ARC; - else if (SP_IS_STAR(saved_item)) + } else if (dynamic_cast<SPStar *>(saved_item)) { object_verb = SP_VERB_CONTEXT_STAR; - else if (SP_IS_SPIRAL(saved_item)) + } else if (dynamic_cast<SPSpiral *>(saved_item)) { object_verb = SP_VERB_CONTEXT_SPIRAL; - else if (SP_IS_OFFSET(saved_item)) { - if (SP_OFFSET(saved_item)->sourceHref) - object_verb = SP_VERB_SELECTION_LINKED_OFFSET; - else - object_verb = SP_VERB_SELECTION_DYNAMIC_OFFSET; + } else { + SPOffset *offset = dynamic_cast<SPOffset *>(saved_item); + if (offset) { + if (offset->sourceHref) { + object_verb = SP_VERB_SELECTION_LINKED_OFFSET; + } else { + object_verb = SP_VERB_SELECTION_DYNAMIC_OFFSET; + } + } } // for drag, this is done by ungrabbed_handler, but for click we must do it here @@ -184,8 +192,9 @@ KnotHolder::knot_moved_handler(SPKnot *knot, Geom::Point const &p, guint state) } } - if (SP_IS_SHAPE (item)) { - SP_SHAPE (item)->set_shape(); + SPShape *shape = dynamic_cast<SPShape *>(item); + if (shape) { + shape->set_shape(); } this->update_knots(); @@ -210,45 +219,42 @@ KnotHolder::knot_ungrabbed_handler(SPKnot */*knot*/, guint) /* do cleanup tasks (e.g., for LPE items write the parameter values * that were changed by dragging the handle to SVG) */ - if (dynamic_cast<SPLPEItem*> (object)) { + SPLPEItem *lpeItem = dynamic_cast<SPLPEItem *>(object); + if (lpeItem) { // This writes all parameters to SVG. Is this sufficiently efficient or should we only // write the ones that were changed? - SPLPEItem * lpeitem = SP_LPE_ITEM(object); - if (lpeitem) { - Inkscape::LivePathEffect::Effect *lpe = lpeitem->getCurrentLPE(); - if (lpe) { - LivePathEffectObject *lpeobj = lpe->getLPEObj(); - lpeobj->updateRepr(); - } + Inkscape::LivePathEffect::Effect *lpe = lpeItem->getCurrentLPE(); + if (lpe) { + LivePathEffectObject *lpeobj = lpe->getLPEObj(); + lpeobj->updateRepr(); } } unsigned int object_verb = SP_VERB_NONE; - if (SP_IS_RECT(object)) + // TODO extract duplicated blocks: + if (dynamic_cast<SPRect *>(object)) { object_verb = SP_VERB_CONTEXT_RECT; - else if (SP_IS_BOX3D(object)) + } else if (dynamic_cast<SPBox3D *>(object)) { object_verb = SP_VERB_CONTEXT_3DBOX; - else if (SP_IS_GENERICELLIPSE(object)) + } else if (dynamic_cast<SPGenericEllipse *>(object)) { object_verb = SP_VERB_CONTEXT_ARC; - else if (SP_IS_STAR(object)) + } else if (dynamic_cast<SPStar *>(object)) { object_verb = SP_VERB_CONTEXT_STAR; - else if (SP_IS_SPIRAL(object)) + } else if (dynamic_cast<SPSpiral *>(object)) { object_verb = SP_VERB_CONTEXT_SPIRAL; - else if (SP_IS_OFFSET(object)) { - if (SP_OFFSET(object)->sourceHref) - object_verb = SP_VERB_SELECTION_LINKED_OFFSET; - else - object_verb = SP_VERB_SELECTION_DYNAMIC_OFFSET; - } - if (object) { //increasingly aggressive sanity checks - if (object->document) { - if (object_verb <= SP_VERB_LAST && object_verb >= SP_VERB_INVALID) { - DocumentUndo::done(object->document, object_verb, - _("Move handle")); + } else { + SPOffset *offset = dynamic_cast<SPOffset *>(object); + if (offset) { + if (offset->sourceHref) { + object_verb = SP_VERB_SELECTION_LINKED_OFFSET; + } else { + object_verb = SP_VERB_SELECTION_DYNAMIC_OFFSET; } } - } //else { abort(); } + } + + DocumentUndo::done(object->document, object_verb, _("Move handle")); } } @@ -261,7 +267,7 @@ void KnotHolder::add(KnotHolderEntity *e) void KnotHolder::add_pattern_knotholder() { - if ((item->style->fill.isPaintserver()) && SP_IS_PATTERN(item->style->getFillPaintServer())) { + if ((item->style->fill.isPaintserver()) && dynamic_cast<SPPattern *>(item->style->getFillPaintServer())) { PatternKnotHolderEntityXY *entity_xy = new PatternKnotHolderEntityXY(true); PatternKnotHolderEntityAngle *entity_angle = new PatternKnotHolderEntityAngle(true); PatternKnotHolderEntityScale *entity_scale = new PatternKnotHolderEntityScale(true); @@ -283,7 +289,7 @@ void KnotHolder::add_pattern_knotholder() entity.push_back(entity_scale); } - if ((item->style->stroke.isPaintserver()) && SP_IS_PATTERN(item->style->getStrokePaintServer())) { + if ((item->style->stroke.isPaintserver()) && dynamic_cast<SPPattern *>(item->style->getStrokePaintServer())) { PatternKnotHolderEntityXY *entity_xy = new PatternKnotHolderEntityXY(false); PatternKnotHolderEntityAngle *entity_angle = new PatternKnotHolderEntityAngle(false); PatternKnotHolderEntityScale *entity_scale = new PatternKnotHolderEntityScale(false); diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index b267c92ed..a3964f553 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -34,6 +34,7 @@ #include "ui/tool/selectable-control-point.h" #include "ui/tool/node.h" #include "ui/tools/node-tool.h" +#include <util/units.h> // TODO due to internal breakage in glibmm headers, this must be last: #include <glibmm/i18n.h> @@ -172,9 +173,9 @@ void LPEFilletChamfer::toggleHide() for (std::vector<Point>::const_iterator point_it = filletChamferData.begin(); point_it != filletChamferData.end(); ++point_it) { if (hide_knots) { - result.push_back(Point((*point_it)[X], abs((*point_it)[Y]) * -1)); + result.push_back(Point((*point_it)[X], std::abs((*point_it)[Y]) * -1)); } else { - result.push_back(Point((*point_it)[X], abs((*point_it)[Y]))); + result.push_back(Point((*point_it)[X], std::abs((*point_it)[Y]))); } } fillet_chamfer_values.param_set_and_write_new_value(result); @@ -211,7 +212,8 @@ void LPEFilletChamfer::updateFillet() { double power = 0; if (!flexible) { - power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), "px") * -1; + Inkscape::Util::Unit const *doc_units = SP_ACTIVE_DESKTOP->namedview->doc_units; + power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), doc_units->abbr) * -1; } else { power = radius; } @@ -589,11 +591,11 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in) } int type = 0; if(path_it->closed() && last){ - type = abs(filletChamferData[counter - counterCurves][Y]); + type = std::abs(filletChamferData[counter - counterCurves][Y]); } else if (!path_it->closed() && last){ //0 } else { - type = abs(filletChamferData[counter + 1][Y]); + type = std::abs(filletChamferData[counter + 1][Y]); } if (type == 3 || type == 4) { if (type == 4) { diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index 6f6838c81..c070cf17b 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -308,6 +308,9 @@ void LPEPerspectiveEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { original_bbox(lpeitem); + SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); + item->apply_to_clippath(item); + item->apply_to_mask(item); setDefaults(); } diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 58d733b53..03a10807a 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -659,6 +659,15 @@ LPEPowerStroke::doEffect_path (std::vector<Geom::Path> const & path_in) ts.push_back( Point( pwd2_in.domain().max(), (end_linecap==LINECAP_ZERO_WIDTH) ? 0. : ts.back()[Geom::Y]) ); } + + // do the interpolation in a coordinate system that is more alike to the on-canvas knots, + // instead of the heavily compressed coordinate system of (segment_no offset, Y) in which the knots are stored + double pwd2_in_arclength = length(pwd2_in); + double xcoord_scaling = pwd2_in_arclength / ts.back()[Geom::X]; + for (std::size_t i = 0, e = ts.size(); i < e; ++i) { + ts[i][Geom::X] *= xcoord_scaling; + } + // create stroke path where points (x,y) := (t, offset) Geom::Interpolate::Interpolator *interpolator = Geom::Interpolate::Interpolator::create(static_cast<Geom::Interpolate::InterpolatorType>(interpolator_type.get_value())); if (Geom::Interpolate::CubicBezierJohan *johan = dynamic_cast<Geom::Interpolate::CubicBezierJohan*>(interpolator)) { @@ -670,6 +679,9 @@ LPEPowerStroke::doEffect_path (std::vector<Geom::Path> const & path_in) Geom::Path strokepath = interpolator->interpolateToPath(ts); delete interpolator; + // apply the inverse knot-xcoord scaling that was applied before the interpolation + strokepath *= Scale(1/xcoord_scaling, 1); + D2<Piecewise<SBasis> > patternd2 = make_cuts_independent(strokepath.toPwSb()); Piecewise<SBasis> x = Piecewise<SBasis>(patternd2[0]); Piecewise<SBasis> y = Piecewise<SBasis>(patternd2[1]); diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index e2b1aba61..db24a9735 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -175,13 +175,8 @@ void FilletChamferPointArrayParam::recalculate_controlpoints_for_new_pwd2( last_pathv[counterPaths][counter - offset].initialPoint(), 0.1))) { if ( curve_it2 == curve_endit) { - if (last_pathv[counterPaths].size() < pathv[counterPaths].size()) { - offset = abs(last_pathv[counterPaths].size() - - pathv[counterPaths].size()); - } else if (last_pathv[counterPaths].size() > - pathv[counterPaths].size()) { - offset = (abs(last_pathv[counterPaths].size() - - pathv[counterPaths].size())) * -1; + if (last_pathv[counterPaths].size() != pathv[counterPaths].size()) { + offset = (last_pathv[counterPaths].size() - pathv[counterPaths].size()) * -1; } else { offset = 0; } diff --git a/src/live_effects/parameter/powerstrokepointarray.cpp b/src/live_effects/parameter/powerstrokepointarray.cpp index 851b12ef8..e0c2f4c68 100644 --- a/src/live_effects/parameter/powerstrokepointarray.cpp +++ b/src/live_effects/parameter/powerstrokepointarray.cpp @@ -8,17 +8,13 @@ #include "live_effects/parameter/powerstrokepointarray.h" #include "live_effects/effect.h" -#include "svg/svg.h" -#include "svg/stringstream.h" #include "knotholder.h" #include "sp-lpe-item.h" #include <2geom/piecewise.h> #include <2geom/sbasis-geometric.h> -// needed for on-canvas editting: -#include "desktop.h" -#include "live_effects/lpeobject.h" +#include "preferences.h" // for proportional stroke/path scaling behavior #include <glibmm/i18n.h> @@ -44,38 +40,25 @@ Gtk::Widget * PowerStrokePointArrayParam::param_newWidget() { return NULL; -/* - Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = Gtk::manage( - new Inkscape::UI::Widget::RegisteredTransformedPoint( param_label, - param_tooltip, - param_key, - *param_wr, - param_effect->getRepr(), - param_effect->getSPDoc() ) ); - // TODO: fix to get correct desktop (don't use SP_ACTIVE_DESKTOP) - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Geom::Affine transf = desktop->doc2dt(); - pointwdg->setTransform(transf); - pointwdg->setValue( *this ); - pointwdg->clearProgrammatically(); - pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter")); - - Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() ); - static_cast<Gtk::HBox*>(hbox)->pack_start(*pointwdg, true, true); - static_cast<Gtk::HBox*>(hbox)->show_all_children(); - - return dynamic_cast<Gtk::Widget *> (hbox); -*/ } -void PowerStrokePointArrayParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/) +void PowerStrokePointArrayParam::param_transform_multiply(Geom::Affine const &postmul, bool /*set*/) { - std::vector<Geom::Point> result; - for (std::vector<Geom::Point>::const_iterator point_it = _vector.begin(); point_it != _vector.end(); ++point_it) { - Geom::Coord A = (*point_it)[Geom::Y] * ((postmul.expansionX() + postmul.expansionY()) / 2); - result.push_back(Geom::Point((*point_it)[Geom::X], A)); + // Check if proportional stroke-width scaling is on + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool transform_stroke = prefs ? prefs->getBool("/options/transform/stroke", true) : true; + if (transform_stroke) { + std::vector<Geom::Point> result; + result.reserve(_vector.size()); // reserve space for the points that will be added in the for loop + for (std::vector<Geom::Point>::const_iterator point_it = _vector.begin(), e = _vector.end(); + point_it != e; ++point_it) + { + // scale each width knot with the average scaling in X and Y + Geom::Coord const A = (*point_it)[Geom::Y] * ((postmul.expansionX() + postmul.expansionY()) / 2); + result.push_back(Geom::Point((*point_it)[Geom::X], A)); + } + param_set_and_write_new_value(result); } - param_set_and_write_new_value(result); } /** call this method to recalculate the controlpoints such that they stay at the same location relative to the new path. Useful after adding/deleting nodes to the path.*/ diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index fe241381f..0c3f9cde7 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -66,8 +66,9 @@ sp_selected_path_combine(SPDesktop *desktop) GSList *to_paths = NULL; for (GSList *i = items; i != NULL; i = i->next) { SPItem *item = (SPItem *) i->data; - if (!SP_IS_PATH(item) && !SP_IS_GROUP(item)) + if (!dynamic_cast<SPPath *>(item) && !dynamic_cast<SPGroup *>(item)) { to_paths = g_slist_prepend(to_paths, item); + } } GSList *converted = NULL; bool did = sp_item_list_to_curves(to_paths, &items, &converted); @@ -99,7 +100,8 @@ sp_selected_path_combine(SPDesktop *desktop) for (GSList *i = items; i != NULL; i = i->next) { // going from top to bottom SPItem *item = (SPItem *) i->data; - if (!SP_IS_PATH(item)) { + SPPath *path = dynamic_cast<SPPath *>(item); + if (!path) { continue; } @@ -108,7 +110,7 @@ sp_selected_path_combine(SPDesktop *desktop) did = true; } - SPCurve *c = SP_PATH(item)->get_curve_for_edit(); + SPCurve *c = path->get_curve_for_edit(); if (first == NULL) { // this is the topmost path first = item; parent = first->getRepr()->parent(); @@ -204,12 +206,11 @@ sp_selected_path_break_apart(SPDesktop *desktop) SPItem *item = (SPItem *) items->data; - if (!SP_IS_PATH(item)) { + SPPath *path = dynamic_cast<SPPath *>(item); + if (!path) { continue; } - SPPath *path = SP_PATH(item); - SPCurve *curve = path->get_curve_for_edit(); if (curve == NULL) { continue; @@ -366,17 +367,20 @@ sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_selec items != NULL; items = items->next) { - SPItem *item = SP_ITEM(items->data); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data)); + g_assert(item != NULL); SPDocument *document = item->document; + SPGroup *group = dynamic_cast<SPGroup *>(item); if ( skip_all_lpeitems && - SP_IS_LPE_ITEM(item) && - !SP_IS_GROUP(item) ) // also convert objects in an SPGroup when skip_all_lpeitems is set. + dynamic_cast<SPLPEItem *>(item) && + !group ) // also convert objects in an SPGroup when skip_all_lpeitems is set. { continue; } - if (SP_IS_PATH(item) && !SP_SHAPE(item)->_curve_before_lpe) { + SPPath *path = dynamic_cast<SPPath *>(item); + if (path && !path->_curve_before_lpe) { // remove connector attributes if (item->getAttribute("inkscape:connector-type") != NULL) { item->removeAttribute("inkscape:connection-start"); @@ -388,9 +392,10 @@ sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_selec continue; // already a path, and no path effect } - if (SP_IS_BOX3D(item)) { + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box) { // convert 3D box to ordinary group of paths; replace the old element in 'selected' with the new group - Inkscape::XML::Node *repr = box3d_convert_to_group(SP_BOX3D(item))->getRepr(); + Inkscape::XML::Node *repr = box3d_convert_to_group(box)->getRepr(); if (repr) { *to_select = g_slist_prepend (*to_select, repr); @@ -401,9 +406,9 @@ sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_selec continue; } - if (SP_IS_GROUP(item)) { - SP_LPE_ITEM(item)->removeAllPathEffects(true); - GSList *item_list = sp_item_group_item_list(SP_GROUP(item)); + if (group) { + group->removeAllPathEffects(true); + GSList *item_list = sp_item_group_item_list(group); GSList *item_to_select = NULL; GSList *item_selected = NULL; @@ -480,7 +485,7 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) Inkscape::XML::Document *xml_doc = item->getRepr()->document(); - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + if (dynamic_cast<SPText *>(item) || dynamic_cast<SPFlowtext *>(item)) { // Special treatment for text: convert each glyph to separate path, then group the paths Inkscape::XML::Node *g_repr = xml_doc->createElement("svg:g"); g_repr->setAttribute("transform", item->getRepr()->attribute("transform")); @@ -497,7 +502,7 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) g_repr->setAttribute("inkscape:transform-center-y", item->getRepr()->attribute("inkscape:transform-center-y"), false); /* Whole text's style */ gchar *style_str = sp_style_write_difference(item->style, - item->parent->style); + item->parent ? item->parent->style : NULL); // TODO investigate posibility g_repr->setAttribute("style", style_str); g_free(style_str); Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin(); @@ -514,11 +519,11 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) if (!rawptr || !SP_IS_OBJECT(rawptr)) // no source for glyph, abort break; pos_obj = SP_OBJECT(rawptr); - while (SP_IS_STRING(pos_obj) && pos_obj->parent) { + while (dynamic_cast<SPString const *>(pos_obj) && pos_obj->parent) { pos_obj = pos_obj->parent; // SPStrings don't have style } gchar *style_str = sp_style_write_difference(pos_obj->style, - pos_obj->parent->style); + pos_obj->parent ? pos_obj->parent->style : NULL); // TODO investigate posibility // get path from iter to iter_next: SPCurve *curve = te_get_layout(item)->convertToCurves(iter, iter_next); @@ -555,8 +560,11 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) } SPCurve *curve = NULL; - if (SP_IS_SHAPE(item)) { - curve = SP_SHAPE(item)->getCurve(); + { + SPShape *shape = dynamic_cast<SPShape *>(item); + if (shape) { + curve = shape->getCurve(); + } } if (!curve) @@ -575,7 +583,7 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) repr->setAttribute("transform", item->getRepr()->attribute("transform")); /* Style */ gchar *style_str = sp_style_write_difference(item->style, - item->parent->style); + item->parent ? item->parent->style : NULL); // TODO investigate posibility repr->setAttribute("style", style_str); g_free(style_str); @@ -622,12 +630,12 @@ sp_selected_path_reverse(SPDesktop *desktop) for (GSList *i = items; i != NULL; i = i->next) { - if (!SP_IS_PATH(i->data)) { + SPPath *path = dynamic_cast<SPPath *>(static_cast<SPObject *>(i->data)); + if (!path) { continue; } did = true; - SPPath *path = SP_PATH(i->data); SPCurve *rcurve = path->get_curve_reference()->create_reverse(); diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index fa872ead1..c81646d6c 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -284,11 +284,12 @@ void SelectionHelper::fixSelection(SPDesktop *dt) GSList const *selList = selection->itemList(); for( GSList const *i = selList; i; i = i->next ) { - if( SP_IS_ITEM(i->data) && - !dt->isLayer(SP_ITEM(i->data)) && - (!SP_ITEM(i->data)->isLocked())) + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); + if( item && + !dt->isLayer(item) && + (!item->isLocked())) { - items = g_slist_prepend(items, SP_ITEM(i->data)); + items = g_slist_prepend(items, item); } } @@ -332,18 +333,27 @@ static void sp_selection_copy_impl(GSList const *items, GSList **clip, Inkscape: sorted_items = g_slist_sort(static_cast<GSList *>(sorted_items), (GCompareFunc) sp_object_compare_position); // Copy item reprs: - for (GSList *i = (GSList *) sorted_items; i != NULL; i = i->next) { - sp_selection_copy_one(SP_OBJECT(i->data)->getRepr(), SP_ITEM(i->data)->i2doc_affine(), clip, xml_doc); + for (GSList *i = sorted_items; i != NULL; i = i->next) { + SPItem *item = dynamic_cast<SPItem *>(SP_OBJECT(i->data)); + if (item) { + sp_selection_copy_one(item->getRepr(), item->i2doc_affine(), clip, xml_doc); + } else { + g_assert_not_reached(); + } } *clip = g_slist_reverse(*clip); g_slist_free(static_cast<GSList *>(sorted_items)); } +// TODO check if parent parameter should be changed to SPItem, of if the code should handle non-items. static GSList *sp_selection_paste_impl(SPDocument *doc, SPObject *parent, GSList **clip) { Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + SPItem *parentItem = dynamic_cast<SPItem *>(parent); + g_assert(parentItem != NULL); + GSList *copied = NULL; // add objects to document for (GSList *l = *clip; l != NULL; l = l->next) { @@ -351,7 +361,7 @@ static GSList *sp_selection_paste_impl(SPDocument *doc, SPObject *parent, GSList Inkscape::XML::Node *copy = repr->duplicate(xml_doc); // premultiply the item transform by the accumulated parent transform in the paste layer - Geom::Affine local(SP_ITEM(parent)->i2doc_affine()); + Geom::Affine local(parentItem->i2doc_affine()); if (!local.isIdentity()) { gchar const *t_str = copy->attribute("transform"); Geom::Affine item_t(Geom::identity()); @@ -428,7 +438,7 @@ static void add_ids_recursive(std::vector<const gchar *> &ids, SPObject *obj) if (obj) { ids.push_back(obj->getId()); - if (SP_IS_GROUP(obj)) { + if (dynamic_cast<SPGroup *>(obj)) { for (SPObject *child = obj->firstChild() ; child; child = child->getNext() ) { add_ids_recursive(ids, child); } @@ -484,8 +494,9 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) if (fork_livepatheffects) { SPObject *new_obj = doc->getObjectByRepr(copy); - if (new_obj && SP_IS_LPE_ITEM(new_obj)) { - SP_LPE_ITEM(new_obj)->forkPathEffectsIfNecessary(1); + SPLPEItem *newLPEObj = dynamic_cast<SPLPEItem *>(new_obj); + if (newLPEObj) { + newLPEObj->forkPathEffectsIfNecessary(1); } } @@ -501,8 +512,9 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) for (unsigned int i = 0; i < old_ids.size(); i++) { const gchar *id = old_ids[i]; SPObject *old_clone = doc->getObjectById(id); - if (SP_IS_USE(old_clone)) { - SPItem *orig = SP_USE(old_clone)->get_original(); + SPUse *use = dynamic_cast<SPUse *>(old_clone); + if (use) { + SPItem *orig = use->get_original(); if (!orig) // orphaned continue; for (unsigned int j = 0; j < old_ids.size(); j++) { @@ -516,13 +528,16 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) g_free(newref); } } - } else if (SP_IS_OFFSET(old_clone)) { - for (guint j = 0; j < old_ids.size(); j++) { - gchar *source_href = SP_OFFSET(old_clone)->sourceHref; - if (source_href && source_href[0]=='#' && !strcmp(source_href+1, old_ids[j])) { - gchar *newref = g_strdup_printf("#%s", new_ids[j]); - doc->getObjectById(new_ids[i])->getRepr()->setAttribute("xlink:href", newref); - g_free(newref); + } else { + SPOffset *offset = dynamic_cast<SPOffset *>(old_clone); + if (offset) { + for (guint j = 0; j < old_ids.size(); j++) { + gchar *source_href = offset->sourceHref; + if (source_href && source_href[0]=='#' && !strcmp(source_href+1, old_ids[j])) { + gchar *newref = g_strdup_printf("#%s", new_ids[j]); + doc->getObjectById(new_ids[i])->getRepr()->setAttribute("xlink:href", newref); + g_free(newref); + } } } } @@ -548,8 +563,9 @@ void sp_edit_clear_all(Inkscape::Selection *selection) SPDocument *doc = selection->layers()->getDocument(); selection->clear(); - g_return_if_fail(SP_IS_GROUP(selection->layers()->currentLayer())); - GSList *items = sp_item_group_item_list(SP_GROUP(selection->layers()->currentLayer())); + SPGroup *group = dynamic_cast<SPGroup *>(selection->layers()->currentLayer()); + g_return_if_fail(group != NULL); + GSList *items = sp_item_group_item_list(group); while (items) { reinterpret_cast<SPObject*>(items->data)->deleteObject(); @@ -573,17 +589,18 @@ void sp_edit_clear_all(Inkscape::Selection *selection) GSList *get_all_items(GSList *list, SPObject *from, SPDesktop *desktop, bool onlyvisible, bool onlysensitive, bool ingroups, GSList const *exclude) { for ( SPObject *child = from->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child) && - !desktop->isLayer(SP_ITEM(child)) && - (!onlysensitive || !SP_ITEM(child)->isLocked()) && - (!onlyvisible || !desktop->itemIsHidden(SP_ITEM(child))) && + SPItem *item = dynamic_cast<SPItem *>(child); + if (item && + !desktop->isLayer(item) && + (!onlysensitive || !item->isLocked()) && + (!onlyvisible || !desktop->itemIsHidden(item)) && (!exclude || !g_slist_find(const_cast<GSList *>(exclude), child)) ) { - list = g_slist_prepend(list, SP_ITEM(child)); + list = g_slist_prepend(list, item); } - if (ingroups || (SP_IS_ITEM(child) && desktop->isLayer(SP_ITEM(child)))) { + if (ingroups || (item && desktop->isLayer(item))) { list = get_all_items(list, child, desktop, onlyvisible, onlysensitive, ingroups, exclude); } } @@ -598,7 +615,7 @@ static void sp_edit_select_all_full(SPDesktop *dt, bool force_all_layers, bool i Inkscape::Selection *selection = sp_desktop_selection(dt); - g_return_if_fail(SP_IS_GROUP(dt->currentLayer())); + g_return_if_fail(dynamic_cast<SPGroup *>(dt->currentLayer())); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); PrefsSelectionContext inlayer = (PrefsSelectionContext) prefs->getInt("/options/kbselection/inlayer", PREFS_SELECTION_LAYER); @@ -617,14 +634,14 @@ static void sp_edit_select_all_full(SPDesktop *dt, bool force_all_layers, bool i switch (inlayer) { case PREFS_SELECTION_LAYER: { - if ( (onlysensitive && SP_ITEM(dt->currentLayer())->isLocked()) || - (onlyvisible && dt->itemIsHidden(SP_ITEM(dt->currentLayer()))) ) + if ( (onlysensitive && dynamic_cast<SPItem *>(dt->currentLayer())->isLocked()) || + (onlyvisible && dt->itemIsHidden(dynamic_cast<SPItem *>(dt->currentLayer()))) ) return; - GSList *all_items = sp_item_group_item_list(SP_GROUP(dt->currentLayer())); + GSList *all_items = sp_item_group_item_list(dynamic_cast<SPGroup *>(dt->currentLayer())); for (GSList *i = all_items; i; i = i->next) { - SPItem *item = SP_ITEM(i->data); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); if (item && (!onlysensitive || !item->isLocked())) { if (!onlyvisible || !dt->itemIsHidden(item)) { @@ -703,7 +720,7 @@ static void sp_selection_group_impl(GSList *p, Inkscape::XML::Node *group, Inksc Geom::Affine item_t(Geom::identity()); if (t_str) sp_svg_transform_read(t_str, &item_t); - item_t *= SP_ITEM(doc->getObjectByRepr(current->parent()))->i2doc_affine(); + item_t *= dynamic_cast<SPItem *>(doc->getObjectByRepr(current->parent()))->i2doc_affine(); // FIXME: when moving both clone and original from a transformed group (either by // grouping into another parent, or by cut/paste) the transform from the original's // parent becomes embedded into original itself, and this affects its clones. Fix @@ -794,7 +811,7 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) GSList *groups = NULL; for (GSList *item = old_select; item; item = item->next) { SPItem *obj = static_cast<SPItem*>(item->data); - if (SP_IS_GROUP(obj)) { + if (dynamic_cast<SPGroup *>(obj)) { groups = g_slist_prepend(groups, obj); } } @@ -815,8 +832,8 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) SPUse *use = dynamic_cast<SPUse *>(static_cast<SPItem *>(item->data)); SPItem *original = use; - while (SP_IS_USE(original)) { - original = SP_USE(original)->get_original(); + while (dynamic_cast<SPUse *>(original)) { + original = dynamic_cast<SPUse *>(original)->get_original(); } if (g_slist_find(groups, original) != NULL) { @@ -843,7 +860,7 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) // ungroup only the groups marked earlier if (g_slist_find(groups, item->data) != NULL) { GSList *children = NULL; - sp_item_group_ungroup(SP_GROUP(obj), &children, false); + sp_item_group_ungroup(dynamic_cast<SPGroup *>(obj), &children, false); // add the items resulting from ungrouping to the selection new_select = g_slist_concat(new_select, children); item->data = NULL; // zero out the original pointer, which is no longer valid @@ -868,11 +885,12 @@ sp_degroup_list(GSList *items) GSList *out = NULL; bool has_groups = false; for (GSList *item = items; item; item = item->next) { - if (!SP_IS_GROUP(item->data)) { + SPGroup *group = dynamic_cast<SPGroup *>(static_cast<SPObject *>(item->data)); + if (!group) { out = g_slist_prepend(out, item->data); } else { has_groups = true; - GSList *members = sp_item_group_item_list(SP_GROUP(item->data)); + GSList *members = sp_item_group_item_list(group); for (GSList *member = members; member; member = member->next) { out = g_slist_prepend(out, member->data); } @@ -899,7 +917,7 @@ sp_item_list_common_parent_group(GSList const *items) } SPObject *parent = SP_OBJECT(items->data)->parent; // Strictly speaking this CAN happen, if user selects <svg> from Inkscape::XML editor - if (!SP_IS_GROUP(parent)) { + if (!dynamic_cast<SPGroup *>(parent)) { return NULL; } for (items = items->next; items; items = items->next) { @@ -908,7 +926,7 @@ sp_item_list_common_parent_group(GSList const *items) } } - return SP_GROUP(parent); + return dynamic_cast<SPGroup *>(parent); } /** Finds out the minimum common bbox of the selected items. */ @@ -928,7 +946,7 @@ enclose_items(GSList const *items) static SPObject *prev_sibling(SPObject *child) { SPObject *prev = 0; - if ( child && SP_IS_GROUP(child->parent) ) { + if ( child && dynamic_cast<SPGroup *>(child->parent) ) { prev = child->getPrev(); } return prev; @@ -965,8 +983,9 @@ sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) // for each selected object, find the next sibling for (SPObject *newref = child->next; newref; newref = newref->next) { // if the sibling is an item AND overlaps our selection, - if (SP_IS_ITEM(newref)) { - Geom::OptRect newref_bbox = SP_ITEM(newref)->desktopVisualBounds(); + SPItem *newItem = dynamic_cast<SPItem *>(newref); + if (newItem) { + Geom::OptRect newref_bbox = newItem->desktopVisualBounds(); if ( newref_bbox && selected->intersects(*newref_bbox) ) { // AND if it's not one of our selected objects, if (!g_slist_find(const_cast<GSList *>(items), newref)) { @@ -1050,8 +1069,9 @@ void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) // for each selected object, find the prev sibling for (SPObject *newref = prev_sibling(child); newref; newref = prev_sibling(newref)) { // if the sibling is an item AND overlaps our selection, - if (SP_IS_ITEM(newref)) { - Geom::OptRect ref_bbox = SP_ITEM(newref)->desktopVisualBounds(); + SPItem *newItem = dynamic_cast<SPItem *>(newref); + if (newItem) { + Geom::OptRect ref_bbox = newItem->desktopVisualBounds(); if ( ref_bbox && selected->intersects(*ref_bbox) ) { // AND if it's not one of our selected objects, if (!g_slist_find(const_cast<GSList *>(items), newref)) { @@ -1105,9 +1125,9 @@ void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *des Inkscape::XML::Node *repr = static_cast<Inkscape::XML::Node *>(l->data); pp = document->getObjectByRepr(repr->parent()); minpos = 0; - g_assert(SP_IS_GROUP(pp)); + g_assert(dynamic_cast<SPGroup *>(pp)); pc = pp->firstChild(); - while (!SP_IS_ITEM(pc)) { + while (!dynamic_cast<SPItem *>(pc)) { minpos += 1; pc = pc->next; } @@ -1162,8 +1182,8 @@ take_style_from_item(SPObject *object) if (css == NULL) return NULL; - if ((SP_IS_GROUP(object) && object->children) || - (SP_IS_TEXT(object) && object->children && object->children->next == NULL)) { + if ((dynamic_cast<SPGroup *>(object) && object->children) || + (dynamic_cast<SPText *>(object) && object->children && object->children->next == NULL)) { // if this is a text with exactly one tspan child, merge the style of that tspan as well // If this is a group, merge the style of its topmost (last) child with style for (SPObject *last_element = object->lastChild(); last_element != NULL; last_element = last_element->getPrev()) { @@ -1178,14 +1198,16 @@ take_style_from_item(SPObject *object) } } - if (!(SP_IS_TEXT(object) || SP_IS_TSPAN(object) || SP_IS_TREF(object) || SP_IS_STRING(object))) { + if (!(dynamic_cast<SPText *>(object) || dynamic_cast<SPTSpan *>(object) || dynamic_cast<SPTRef *>(object) || dynamic_cast<SPString *>(object))) { // do not copy text properties from non-text objects, it's confusing css = sp_css_attr_unset_text(css); } - if (SP_IS_ITEM(object)) { + + SPItem *item = dynamic_cast<SPItem *>(object); + if (item) { // FIXME: also transform gradient/pattern fills, by forking? NO, this must be nondestructive - double ex = SP_ITEM(object)->i2doc_affine().descrim(); + double ex = item->i2doc_affine().descrim(); if (ex != 1.0) { css = sp_css_attr_scale(css, ex); } @@ -1425,22 +1447,23 @@ selection_contains_original(SPItem *item, Inkscape::Selection *selection) { bool contains_original = false; - bool is_use = SP_IS_USE(item); SPItem *item_use = item; SPItem *item_use_first = item; - while (is_use && item_use && !contains_original) + SPUse *use = dynamic_cast<SPUse *>(item_use); + while (use && item_use && !contains_original) { - item_use = SP_USE(item_use)->get_original(); + item_use = use->get_original(); + use = dynamic_cast<SPUse *>(item_use); contains_original |= selection->includes(item_use); if (item_use == item_use_first) break; - is_use = SP_IS_USE(item_use); } // If it's a tref, check whether the object containing the character // data is part of the selection - if (!contains_original && SP_IS_TREF(item)) { - contains_original = selection->includes(SP_TREF(item)->getObjectReferredTo()); + SPTRef *tref = dynamic_cast<SPTRef *>(item); + if (!contains_original && tref) { + contains_original = selection->includes(tref->getObjectReferredTo()); } return contains_original; @@ -1452,10 +1475,12 @@ selection_contains_both_clone_and_original(Inkscape::Selection *selection) { bool clone_with_original = false; for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { - SPItem *item = SP_ITEM(l->data); - clone_with_original |= selection_contains_original(item, selection); - if (clone_with_original) - break; + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(l->data)); + if (item) { + clone_with_original |= selection_contains_original(item, selection); + if (clone_with_original) + break; + } } return clone_with_original; } @@ -1495,9 +1520,9 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons } for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { - SPItem *item = SP_ITEM(l->data); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(l->data)); - if( SP_IS_ROOT(item) ) { + if( dynamic_cast<SPRoot *>(item) ) { // An SVG element cannot have a transform. We could change 'x' and 'y' in response // to a translation... but leave that for another day. selection->desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Cannot transform an embedded SVG.")); @@ -1515,24 +1540,32 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons // we're moving both a clone and its original or any ancestor in clone chain? bool transform_clone_with_original = selection_contains_original(item, selection); + // ...both a text-on-path and its path? - bool transform_textpath_with_path = (SP_IS_TEXT_TEXTPATH(item) && selection->includes( sp_textpath_get_path_item(SP_TEXTPATH(item->firstChild())) )); + bool transform_textpath_with_path = ((dynamic_cast<SPText *>(item) && item->firstChild() && dynamic_cast<SPTextPath *>(item->firstChild())) + && selection->includes( sp_textpath_get_path_item(dynamic_cast<SPTextPath *>(item->firstChild())) )); + // ...both a flowtext and its frame? - bool transform_flowtext_with_frame = (SP_IS_FLOWTEXT(item) && selection->includes( SP_FLOWTEXT(item)->get_frame(NULL))); // (only the first frame is checked so far) + bool transform_flowtext_with_frame = (dynamic_cast<SPFlowtext *>(item) && selection->includes( dynamic_cast<SPFlowtext *>(item)->get_frame(NULL))); // (only the first frame is checked so far) + // ...both an offset and its source? - bool transform_offset_with_source = (SP_IS_OFFSET(item) && SP_OFFSET(item)->sourceHref) && selection->includes( sp_offset_get_source(SP_OFFSET(item)) ); + bool transform_offset_with_source = (dynamic_cast<SPOffset *>(item) && dynamic_cast<SPOffset *>(item)->sourceHref) && selection->includes( sp_offset_get_source(dynamic_cast<SPOffset *>(item)) ); // If we're moving a connector, we want to detach it // from shapes that aren't part of the selection, but // leave it attached if they are if (Inkscape::UI::Tools::cc_item_is_connector(item)) { - SPItem *attItem[2]; - SP_PATH(item)->connEndPair.getAttachedItems(attItem); - - for (int n = 0; n < 2; ++n) { - if (!selection->includes(attItem[n])) { - sp_conn_end_detach(item, n); + SPPath *path = dynamic_cast<SPPath *>(item); + if (path) { + SPItem *attItem[2] = {0, 0}; + path->connEndPair.getAttachedItems(attItem); + for (int n = 0; n < 2; ++n) { + if (!selection->includes(attItem[n])) { + sp_conn_end_detach(item, n); + } } + } else { + g_assert_not_reached(); } } @@ -1556,10 +1589,11 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons // apply the inverse of the region's transform to the <use> so that the flow remains // the same (even though the output itself gets transformed) for ( SPObject *region = item->firstChild() ; region ; region = region->getNext() ) { - if (SP_IS_FLOWREGION(region) || SP_IS_FLOWREGIONEXCLUDE(region)) { - for ( SPObject *use = region->firstChild() ; use ; use = use->getNext() ) { - if ( SP_IS_USE(use) ) { - SP_USE(use)->doWriteTransform(use->getRepr(), item->transform.inverse(), NULL, compensate); + if (dynamic_cast<SPFlowregion *>(region) || dynamic_cast<SPFlowregionExclude *>(region)) { + for ( SPObject *item = region->firstChild() ; item ; item = item->getNext() ) { + SPUse *use = dynamic_cast<SPUse *>(item); + if ( use ) { + use->doWriteTransform(use->getRepr(), use->transform.inverse(), NULL, compensate); } } } @@ -1573,7 +1607,15 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons item->readAttr( "transform" ); // calculate the matrix we need to apply to the clone to cancel its induced transform from its original - Geom::Affine parent2dt = SP_ITEM(item->parent)->i2dt_affine(); + Geom::Affine parent2dt; + { + SPItem *parentItem = dynamic_cast<SPItem *>(item->parent); + if (parentItem) { + parent2dt = parentItem->i2dt_affine(); + } else { + g_assert_not_reached(); + } + } Geom::Affine t = parent2dt * affine * parent2dt.inverse(); Geom::Affine t_inv = t.inverse(); Geom::Affine result = t_inv * item->transform * t; @@ -1582,7 +1624,15 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons // we need to cancel out the move compensation, too // find out the clone move, same as in sp_use_move_compensate - Geom::Affine parent = SP_USE(item)->get_parent_transform(); + Geom::Affine parent; + { + SPUse *use = dynamic_cast<SPUse *>(item); + if (use) { + parent = use->get_parent_transform(); + } else { + g_assert_not_reached(); + } + } Geom::Affine clone_move = parent.inverse() * t * parent; if (prefs_parallel) { @@ -1743,8 +1793,12 @@ void sp_selection_rotate_90(SPDesktop *desktop, bool ccw) GSList const *l = selection->itemList(); Geom::Rotate const rot_90(Geom::Point(0, ccw ? 1 : -1)); // pos. or neg. rotation, depending on the value of ccw for (GSList const *l2 = l ; l2 != NULL ; l2 = l2->next) { - SPItem *item = SP_ITEM(l2->data); - sp_item_rotate_rel(item, rot_90); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(l2->data)); + if (item) { + sp_item_rotate_rel(item, rot_90); + } else { + g_assert_not_reached(); + } } DocumentUndo::done(sp_desktop_document(desktop), @@ -1802,7 +1856,7 @@ void sp_select_same_fill_stroke_style(SPDesktop *desktop, gboolean fill, gboolea Inkscape::Selection *selection = sp_desktop_selection (desktop); for (GSList const* sel_iter = selection->itemList(); sel_iter; sel_iter = sel_iter->next) { - SPItem *sel = SP_ITEM(sel_iter->data); + SPItem *sel = dynamic_cast<SPItem *>(static_cast<SPObject *>(sel_iter->data)); GSList *matches = all_list; if (fill) { matches = sp_get_same_fill_or_stroke_color(sel, matches, SP_FILL_COLOR); @@ -1855,8 +1909,12 @@ void sp_select_same_object_type(SPDesktop *desktop) Inkscape::Selection *selection = sp_desktop_selection (desktop); for (GSList const* sel_iter = selection->itemList(); sel_iter; sel_iter = sel_iter->next) { - SPItem *sel = SP_ITEM(sel_iter->data); - matches = sp_get_same_object_type(sel, matches); + SPItem *sel = dynamic_cast<SPItem *>(static_cast<SPObject *>(sel_iter->data)); + if (sel) { + matches = sp_get_same_object_type(sel, matches); + } else { + g_assert_not_reached(); + } } selection->clear(); @@ -1893,10 +1951,14 @@ void sp_select_same_stroke_style(SPDesktop *desktop) Inkscape::Selection *selection = sp_desktop_selection (desktop); for (GSList const* sel_iter = selection->itemList(); sel_iter; sel_iter = sel_iter->next) { - SPItem *sel = SP_ITEM(sel_iter->data); - matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_WIDTH); - matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_DASHES); - matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_MARKERS); + SPItem *sel = dynamic_cast<SPItem *>(static_cast<SPObject *>(sel_iter->data)); + if (sel) { + matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_WIDTH); + matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_DASHES); + matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_MARKERS); + } else { + g_assert_not_reached(); + } } selection->clear(); @@ -1922,45 +1984,49 @@ GSList *sp_get_same_fill_or_stroke_color(SPItem *sel, GSList *src, SPSelectStrok SPIPaint *sel_paint = (type == SP_FILL_COLOR) ? &(sel->style->fill) : &(sel->style->stroke); for (GSList *i = src; i != NULL; i = i->next) { - SPItem *iter = SP_ITEM(i->data); - SPIPaint *iter_paint = (type == SP_FILL_COLOR) ? &(iter->style->fill) : &(iter->style->stroke); - match = false; - if (sel_paint->isColor() && iter_paint->isColor() // color == color comparision doesnt seem to work here. + SPItem *iter = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); + if (iter) { + SPIPaint *iter_paint = (type == SP_FILL_COLOR) ? &(iter->style->fill) : &(iter->style->stroke); + match = false; + if (sel_paint->isColor() && iter_paint->isColor() // color == color comparision doesnt seem to work here. && (sel_paint->value.color.toRGBA32(1.0) == iter_paint->value.color.toRGBA32(1.0))) { - match = true; - } else if (sel_paint->isPaintserver() && iter_paint->isPaintserver()) { + match = true; + } else if (sel_paint->isPaintserver() && iter_paint->isPaintserver()) { - SPPaintServer *sel_server = + SPPaintServer *sel_server = (type == SP_FILL_COLOR) ? sel->style->getFillPaintServer() : sel->style->getStrokePaintServer(); - SPPaintServer *iter_server = + SPPaintServer *iter_server = (type == SP_FILL_COLOR) ? iter->style->getFillPaintServer() : iter->style->getStrokePaintServer(); - if ((SP_IS_LINEARGRADIENT(sel_server) || SP_IS_RADIALGRADIENT(sel_server) || - (SP_IS_GRADIENT(sel_server) && SP_GRADIENT(sel_server)->getVector()->isSwatch())) + if ((dynamic_cast<SPLinearGradient *>(sel_server) || dynamic_cast<SPRadialGradient *>(sel_server) || + (dynamic_cast<SPGradient *>(sel_server) && dynamic_cast<SPGradient *>(sel_server)->getVector()->isSwatch())) && - (SP_IS_LINEARGRADIENT(iter_server) || SP_IS_RADIALGRADIENT(iter_server) || - (SP_IS_GRADIENT(iter_server) && SP_GRADIENT(iter_server)->getVector()->isSwatch()))) { - SPGradient *sel_vector = SP_GRADIENT(sel_server)->getVector(); - SPGradient *iter_vector = SP_GRADIENT(iter_server)->getVector(); - if (sel_vector == iter_vector) { - match = true; - } + (dynamic_cast<SPLinearGradient *>(iter_server) || dynamic_cast<SPRadialGradient *>(iter_server) || + (dynamic_cast<SPGradient *>(iter_server) && dynamic_cast<SPGradient *>(iter_server)->getVector()->isSwatch()))) { + SPGradient *sel_vector = dynamic_cast<SPGradient *>(sel_server)->getVector(); + SPGradient *iter_vector = dynamic_cast<SPGradient *>(iter_server)->getVector(); + if (sel_vector == iter_vector) { + match = true; + } - } else if (SP_IS_PATTERN(sel_server) && SP_IS_PATTERN(iter_server)) { - SPPattern *sel_pat = pattern_getroot(SP_PATTERN(sel_server)); - SPPattern *iter_pat = pattern_getroot(SP_PATTERN(iter_server)); - if (sel_pat == iter_pat) { - match = true; + } else if (dynamic_cast<SPPattern *>(sel_server) && dynamic_cast<SPPattern *>(iter_server)) { + SPPattern *sel_pat = pattern_getroot(dynamic_cast<SPPattern *>(sel_server)); + SPPattern *iter_pat = pattern_getroot(dynamic_cast<SPPattern *>(iter_server)); + if (sel_pat == iter_pat) { + match = true; + } } + } else if (sel_paint->isNone() && iter_paint->isNone()) { + match = true; + } else if (sel_paint->isNoneSet() && iter_paint->isNoneSet()) { + match = true; } - } else if (sel_paint->isNone() && iter_paint->isNone()) { - match = true; - } else if (sel_paint->isNoneSet() && iter_paint->isNoneSet()) { - match = true; - } - if (match) { - matches = g_slist_prepend(matches, iter); + if (match) { + matches = g_slist_prepend(matches, iter); + } + } else { + g_assert_not_reached(); } } @@ -1969,35 +2035,35 @@ GSList *sp_get_same_fill_or_stroke_color(SPItem *sel, GSList *src, SPSelectStrok static bool item_type_match (SPItem *i, SPItem *j) { - if ( SP_IS_RECT(i)) { - return ( SP_IS_RECT(j) ); + if ( dynamic_cast<SPRect *>(i)) { + return ( dynamic_cast<SPRect *>(j) ); - } else if (SP_IS_GENERICELLIPSE(i)) { - return (SP_IS_GENERICELLIPSE(j)); + } else if (dynamic_cast<SPGenericEllipse *>(i)) { + return (dynamic_cast<SPGenericEllipse *>(j)); - } else if (SP_IS_STAR(i) || SP_IS_POLYGON(i)) { - return (SP_IS_STAR(j) || SP_IS_POLYGON(j)) ; + } else if (dynamic_cast<SPStar *>(i) || dynamic_cast<SPPolygon *>(i)) { + return (dynamic_cast<SPStar *>(j) || dynamic_cast<SPPolygon *>(j)) ; - } else if (SP_IS_SPIRAL(i)) { - return (SP_IS_SPIRAL(j)); + } else if (dynamic_cast<SPSpiral *>(i)) { + return (dynamic_cast<SPSpiral *>(j)); - } else if (SP_IS_PATH(i) || SP_IS_LINE(i) || SP_IS_POLYLINE(i)) { - return (SP_IS_PATH(j) || SP_IS_LINE(j) || SP_IS_POLYLINE(j)); + } else if (dynamic_cast<SPPath *>(i) || dynamic_cast<SPLine *>(i) || dynamic_cast<SPPolyLine *>(i)) { + return (dynamic_cast<SPPath *>(j) || dynamic_cast<SPLine *>(j) || dynamic_cast<SPPolyLine *>(j)); - } else if (SP_IS_TEXT(i) || SP_IS_FLOWTEXT(i) || SP_IS_TSPAN(i) || SP_IS_TREF(i) || SP_IS_STRING(i)) { - return (SP_IS_TEXT(j) || SP_IS_FLOWTEXT(j) || SP_IS_TSPAN(j) || SP_IS_TREF(j) || SP_IS_STRING(j)); + } else if (dynamic_cast<SPText *>(i) || dynamic_cast<SPFlowtext *>(i) || dynamic_cast<SPTSpan *>(i) || dynamic_cast<SPTRef *>(i) || dynamic_cast<SPString *>(i)) { + return (dynamic_cast<SPText *>(j) || dynamic_cast<SPFlowtext *>(j) || dynamic_cast<SPTSpan *>(j) || dynamic_cast<SPTRef *>(j) || dynamic_cast<SPString *>(j)); - } else if (SP_IS_USE(i)) { - return (SP_IS_USE(j)) ; + } else if (dynamic_cast<SPUse *>(i)) { + return (dynamic_cast<SPUse *>(j)) ; - } else if (SP_IS_IMAGE(i)) { - return (SP_IS_IMAGE(j)); + } else if (dynamic_cast<SPImage *>(i)) { + return (dynamic_cast<SPImage *>(j)); - } else if (SP_IS_OFFSET(i) && SP_OFFSET(i)->sourceHref) { // Linked offset - return (SP_IS_OFFSET(j) && SP_OFFSET(j)->sourceHref); + } else if (dynamic_cast<SPOffset *>(i) && dynamic_cast<SPOffset *>(i)->sourceHref) { // Linked offset + return (dynamic_cast<SPOffset *>(j) && dynamic_cast<SPOffset *>(j)->sourceHref); - } else if (SP_IS_OFFSET(i) && !SP_OFFSET(i)->sourceHref) { // Dynamic offset - return (SP_IS_OFFSET(j) && !SP_OFFSET(j)->sourceHref); + } else if (dynamic_cast<SPOffset *>(i) && !dynamic_cast<SPOffset *>(i)->sourceHref) { // Dynamic offset + return (dynamic_cast<SPOffset *>(j) && !dynamic_cast<SPOffset *>(j)->sourceHref); } @@ -2013,8 +2079,8 @@ GSList *sp_get_same_object_type(SPItem *sel, GSList *src) GSList *matches = NULL; for (GSList *i = src; i != NULL; i = i->next) { - SPItem *item = SP_ITEM(i->data); - if (item_type_match (sel, item)) { + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); + if (item && item_type_match(sel, item)) { matches = g_slist_prepend (matches, item); } } @@ -2050,31 +2116,32 @@ GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleTy } for (GSList *i = src; i != NULL; i = i->next) { - SPItem *iter = SP_ITEM(i->data); - SPStyle *iter_style = iter->style; - match = false; - - if (type == SP_STROKE_STYLE_WIDTH) { - match = (sel_style->stroke_width.set == iter_style->stroke_width.set); - if (sel_style->stroke_width.set && iter_style->stroke_width.set) { - GSList *objects = NULL; - objects = g_slist_prepend(objects, iter); - SPStyle *iter_style_for_width = sp_style_new (SP_ACTIVE_DOCUMENT); - objects_query_strokewidth (objects, iter_style_for_width); - - if (sel_style_for_width) { - match = (sel_style_for_width->stroke_width.computed == iter_style_for_width->stroke_width.computed); + SPItem *iter = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); + if (iter) { + SPStyle *iter_style = iter->style; + match = false; + + if (type == SP_STROKE_STYLE_WIDTH) { + match = (sel_style->stroke_width.set == iter_style->stroke_width.set); + if (sel_style->stroke_width.set && iter_style->stroke_width.set) { + GSList *objects = NULL; + objects = g_slist_prepend(objects, iter); + SPStyle *iter_style_for_width = sp_style_new (SP_ACTIVE_DOCUMENT); + objects_query_strokewidth (objects, iter_style_for_width); + + if (sel_style_for_width) { + match = (sel_style_for_width->stroke_width.computed == iter_style_for_width->stroke_width.computed); + } + g_slist_free(objects); } - g_slist_free(objects); } - } - else if (type == SP_STROKE_STYLE_DASHES ) { - match = (sel_style->stroke_dasharray.set == iter_style->stroke_dasharray.set); - if (sel_style->stroke_dasharray.set && iter_style->stroke_dasharray.set) { - match = (sel_style->stroke_dasharray.values == iter_style->stroke_dasharray.values); + else if (type == SP_STROKE_STYLE_DASHES ) { + match = (sel_style->stroke_dasharray.set == iter_style->stroke_dasharray.set); + if (sel_style->stroke_dasharray.set && iter_style->stroke_dasharray.set) { + match = (sel_style->stroke_dasharray.values == iter_style->stroke_dasharray.values); + } } - } - else if (type == SP_STROKE_STYLE_MARKERS) { + else if (type == SP_STROKE_STYLE_MARKERS) { match = true; int len = sizeof(sel_style->marker)/sizeof(SPIString); for (int i = 0; i < len; i++) { @@ -2085,10 +2152,13 @@ GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleTy break; } } - } + } - if (match) { - matches = g_slist_prepend(matches, iter); + if (match) { + matches = g_slist_prepend(matches, iter); + } + } else { + g_assert_not_reached(); } } @@ -2435,7 +2505,7 @@ SPItem *next_item_from_list(SPDesktop *desktop, GSList const *items, { SPObject *current=root; while (items) { - SPItem *item=SP_ITEM(items->data); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data)); if ( root->isAncestorOf(item) && ( !only_in_viewport || desktop->isWithinViewport(item) ) ) { @@ -2489,13 +2559,16 @@ SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root, if (PREFS_SELECTION_LAYER != inlayer) { // recurse into sublayers found = next_item<D>(desktop, NULL, object, only_in_viewport, inlayer, onlyvisible, onlysensitive); } - } else if ( SP_IS_ITEM(object) && - ( !only_in_viewport || desktop->isWithinViewport(SP_ITEM(object)) ) && - ( !onlyvisible || !desktop->itemIsHidden(SP_ITEM(object))) && - ( !onlysensitive || !SP_ITEM(object)->isLocked()) && - !desktop->isLayer(SP_ITEM(object)) ) - { - found = SP_ITEM(object); + } else { + SPItem *item = dynamic_cast<SPItem *>(object); + if ( item && + ( !only_in_viewport || desktop->isWithinViewport(item) ) && + ( !onlyvisible || !desktop->itemIsHidden(item)) && + ( !onlysensitive || !item->isLocked()) && + !desktop->isLayer(item) ) + { + found = item; + } } iter = D::next(iter); } @@ -2613,12 +2686,11 @@ sp_selection_relink(SPDesktop *desktop) { SPItem *item = static_cast<SPItem *>(items->data); - if (!SP_IS_USE(item)) - continue; - - item->getRepr()->setAttribute("xlink:href", newref); - item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - relinked = true; + if (dynamic_cast<SPUse *>(item)) { + item->getRepr()->setAttribute("xlink:href", newref); + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + relinked = true; + } } g_free(newref); @@ -2654,7 +2726,7 @@ sp_selection_unlink(SPDesktop *desktop) { SPItem *item = static_cast<SPItem *>(items->data); - if (SP_IS_TEXT(item)) { + if (dynamic_cast<SPText *>(item)) { SPObject *tspan = sp_tref_convert_to_tspan(item); if (tspan) { @@ -2666,22 +2738,24 @@ sp_selection_unlink(SPDesktop *desktop) unlinked = true; } - if (!(SP_IS_USE(item) || SP_IS_TREF(item))) { + if (!(dynamic_cast<SPUse *>(item) || dynamic_cast<SPTRef *>(item))) { // keep the non-use item in the new selection new_select = g_slist_prepend(new_select, item); continue; } - SPItem *unlink; - if (SP_IS_USE(item)) { - unlink = SP_USE(item)->unlink(); + SPItem *unlink = NULL; + SPUse *use = dynamic_cast<SPUse *>(item); + if (use) { + unlink = use->unlink(); // Unable to unlink use (external or invalid href?) if (!unlink) { new_select = g_slist_prepend(new_select, item); continue; } } else /*if (SP_IS_TREF(use))*/ { - unlink = SP_ITEM(sp_tref_convert_to_tspan(item)); + unlink = dynamic_cast<SPItem *>(sp_tref_convert_to_tspan(item)); + g_assert(unlink != NULL); } unlinked = true; @@ -2721,24 +2795,39 @@ sp_select_clone_original(SPDesktop *desktop) } SPItem *original = NULL; - if (SP_IS_USE(item)) { - original = SP_USE(item)->get_original(); - } else if (SP_IS_OFFSET(item) && SP_OFFSET(item)->sourceHref) { - original = sp_offset_get_source(SP_OFFSET(item)); - } else if (SP_IS_TEXT_TEXTPATH(item)) { - original = sp_textpath_get_path_item(SP_TEXTPATH(item->firstChild())); - } else if (SP_IS_FLOWTEXT(item)) { - original = SP_FLOWTEXT(item)->get_frame(NULL); // first frame only - } else if (SP_IS_LPE_ITEM(item)) { - // check if the applied LPE is Clone original, if so, go to the refered path - Inkscape::LivePathEffect::Effect* lpe = SP_LPE_ITEM(item)->getPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL); - if (lpe) { - Inkscape::LivePathEffect::Parameter *lpeparam = lpe->getParameter("linkedpath"); - if (Inkscape::LivePathEffect::OriginalPathParam *pathparam = dynamic_cast<Inkscape::LivePathEffect::OriginalPathParam *>(lpeparam)) { - original = pathparam->getObject(); + SPUse *use = dynamic_cast<SPUse *>(item); + if (use) { + original = use->get_original(); + } else { + SPOffset *offset = dynamic_cast<SPOffset *>(item); + if (offset && offset->sourceHref) { + original = sp_offset_get_source(offset); + } else { + SPText *text = dynamic_cast<SPText *>(item); + SPTextPath *textpath = (text) ? dynamic_cast<SPTextPath *>(text->firstChild()) : NULL; + if (text && textpath) { + original = sp_textpath_get_path_item(textpath); + } else { + SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(item); + if (flowtext) { + original = flowtext->get_frame(NULL); // first frame only + } else { + SPLPEItem *lpeItem = dynamic_cast<SPLPEItem *>(item); + if (lpeItem) { + // check if the applied LPE is Clone original, if so, go to the refered path + Inkscape::LivePathEffect::Effect* lpe = lpeItem->getPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL); + if (lpe) { + Inkscape::LivePathEffect::Parameter *lpeparam = lpe->getParameter("linkedpath"); + if (Inkscape::LivePathEffect::OriginalPathParam *pathparam = dynamic_cast<Inkscape::LivePathEffect::OriginalPathParam *>(lpeparam)) { + original = pathparam->getObject(); + } + } + } + } } } } + if (original == NULL) { // it's an object that we don't know what to do with desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, error); return; @@ -2749,8 +2838,8 @@ sp_select_clone_original(SPDesktop *desktop) return; } - for (SPObject *o = original; o && !SP_IS_ROOT(o); o = o->parent) { - if (SP_IS_DEFS(o)) { + for (SPObject *o = original; o && !dynamic_cast<SPRoot *>(o); o = o->parent) { + if (dynamic_cast<SPDefs *>(o)) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The object you're trying to select is <b>not visible</b> (it is in <defs>)")); return; } @@ -2826,16 +2915,15 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) // add the new clone to the top of the original's parent parent->appendChildRepr(clone); SPObject *clone_obj = desktop->doc()->getObjectById(clone->attribute("id")); - if (SP_IS_LPE_ITEM(clone_obj)) { + SPLPEItem *clone_lpeitem = dynamic_cast<SPLPEItem *>(clone_obj); + if (clone_lpeitem) { gchar *href = g_strdup_printf("#%s", lpe_id); - //sp_lpe_item_add_path_effect( SP_LPE_ITEM(clone_obj), href, false ); - SP_LPE_ITEM(clone_obj)->addPathEffect(href, false); + clone_lpeitem->addPathEffect(href, false); g_free(href); } } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, - _("Fill between strokes")); + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, _("Fill between many")); } else { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select path(s) to fill.")); } @@ -2885,7 +2973,15 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) // bottommost object, after sorting SPObject *parent = SP_OBJECT(items->data)->parent; - Geom::Affine parent_transform(SP_ITEM(parent)->i2doc_affine()); + Geom::Affine parent_transform; + { + SPItem *parentItem = dynamic_cast<SPItem *>(parent); + if (parent) { + parent_transform = parentItem->i2doc_affine(); + } else { + g_assert_not_reached(); + } + } // Create a list of duplicates, to be pasted inside marker element. GSList *repr_copies = NULL; @@ -2926,8 +3022,9 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) } static void sp_selection_to_guides_recursive(SPItem *item, bool wholegroups) { - if (SP_IS_GROUP(item) && !SP_IS_BOX3D(item) && !wholegroups) { - for (GSList *i = sp_item_group_item_list(SP_GROUP(item)); i != NULL; i = i->next) { + SPGroup *group = dynamic_cast<SPGroup *>(item); + if (group && !dynamic_cast<SPBox3D *>(item) && !wholegroups) { + for (GSList *i = sp_item_group_item_list(group); i != NULL; i = i->next) { sp_selection_to_guides_recursive(static_cast<SPItem*>(i->data), wholegroups); } } else { @@ -3019,13 +3116,13 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) // Find out if we have a single group bool single_group = false; - SPObject *the_group = NULL; + SPGroup *the_group = NULL; Geom::Affine transform; if( g_slist_length( items ) == 1 ) { SPObject *object = reinterpret_cast<SPObject *>( items->data ); - if( SP_IS_GROUP( object ) ) { + the_group = dynamic_cast<SPGroup *>(object); + if ( the_group ) { single_group = true; - the_group = object; if( !sp_svg_transform_read( object->getAttribute("transform"), &transform )) transform = Geom::identity(); @@ -3044,7 +3141,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); // Remove transform on group, updating clones. - SP_ITEM(object)->doWriteTransform(object->getRepr(), Geom::identity()); + the_group->doWriteTransform(object->getRepr(), Geom::identity()); // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); @@ -3138,7 +3235,7 @@ void sp_selection_unsymbol(SPDesktop *desktop) // Make sure we have only one object in selection. // Require that we really have a <symbol>. - if( symbol == NULL || !SP_IS_SYMBOL( symbol )) { + if( symbol == NULL || !dynamic_cast<SPSymbol *>( symbol )) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select only one <b>symbol</b> in Symbol dialog to convert to group.")); return; } @@ -3157,7 +3254,7 @@ void sp_selection_unsymbol(SPDesktop *desktop) // group that only adds a transform to the symbol content). if( g_slist_length( children ) == 1 ) { SPObject *object = reinterpret_cast<SPObject *>( children->data ); - if( SP_IS_GROUP( object ) ) { + if ( dynamic_cast<SPGroup *>( object ) ) { if( object->getAttribute("style") == NULL || object->getAttribute("class") == NULL ) { @@ -3236,8 +3333,17 @@ sp_selection_tile(SPDesktop *desktop, bool apply) // bottommost object, after sorting SPObject *parent = SP_OBJECT(items->data)->parent; + - Geom::Affine parent_transform(SP_ITEM(parent)->i2doc_affine()); + Geom::Affine parent_transform; + { + SPItem *parentItem = dynamic_cast<SPItem *>(parent); + if (parentItem) { + parent_transform = parentItem->i2doc_affine(); + } else { + g_assert_not_reached(); + } + } // remember the position of the first item gint pos = SP_OBJECT(items->data)->getRepr()->position(); @@ -3342,20 +3448,22 @@ void sp_selection_untile(SPDesktop *desktop) SPPaintServer *server = item->style->getFillPaintServer(); - if (!SP_IS_PATTERN(server)) + SPPattern *basePat = dynamic_cast<SPPattern *>(server); + if (!basePat) { continue; + } did = true; - SPPattern *pattern = pattern_getroot(SP_PATTERN(server)); + SPPattern *pattern = pattern_getroot(basePat); - Geom::Affine pat_transform = pattern_patternTransform(SP_PATTERN(server)); + Geom::Affine pat_transform = pattern_patternTransform(basePat); pat_transform *= item->transform; for (SPObject *child = pattern->firstChild() ; child != NULL; child = child->next ) { - if (SP_IS_ITEM(child)) { + if (dynamic_cast<SPItem *>(child)) { Inkscape::XML::Node *copy = child->getRepr()->duplicate(xml_doc); - SPItem *i = SP_ITEM(desktop->currentLayer()->appendChildRepr(copy)); + SPItem *i = dynamic_cast<SPItem *>(desktop->currentLayer()->appendChildRepr(copy)); // FIXME: relink clones to the new canvas objects // use SPObject::setid when mental finishes it to steal ids of @@ -3363,10 +3471,14 @@ void sp_selection_untile(SPDesktop *desktop) // this is needed to make sure the new item has curve (simply requestDisplayUpdate does not work) doc->ensureUpToDate(); - Geom::Affine transform( i->transform * pat_transform ); - i->doWriteTransform(i->getRepr(), transform); + if (i) { + Geom::Affine transform( i->transform * pat_transform ); + i->doWriteTransform(i->getRepr(), transform); - new_select = g_slist_prepend(new_select, i); + new_select = g_slist_prepend(new_select, i); + } else { + g_assert_not_reached(); + } } } @@ -3584,7 +3696,15 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) } // Calculate the matrix that will be applied to the image so that it exactly overlaps the source objects - Geom::Affine eek(SP_ITEM(parent_object)->i2dt_affine()); + Geom::Affine eek; + { + SPItem *parentItem = dynamic_cast<SPItem *>(parent_object); + if (parentItem) { + eek = parentItem->i2dt_affine(); + } else { + g_assert_not_reached(); + } + } Geom::Affine t; double shift_x = bbox->min()[Geom::X]; @@ -4042,14 +4162,14 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { SP_OBJECT(i->data)->getRepr()->setAttribute(attributeName, "none"); - if (ungroup_masked && SP_IS_GROUP(i->data)) { + SPGroup *group = dynamic_cast<SPGroup *>(static_cast<SPObject *>(i->data)); + if (ungroup_masked && group) { // if we had previously enclosed masked object in group, // add it to list so we can ungroup it later - SPGroup *item = SP_GROUP(i->data); // ungroup only groups we created when setting clip/mask - if (item->layerMode() == SPGroup::MASK_HELPER) { - items_to_ungroup = g_slist_prepend(items_to_ungroup, item); + if (group->layerMode() == SPGroup::MASK_HELPER) { + items_to_ungroup = g_slist_prepend(items_to_ungroup, group); } } @@ -4101,10 +4221,15 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { // ungroup marked groups added when setting mask for (GSList *i = items_to_ungroup ; NULL != i ; i = i->next) { - items_to_select = g_slist_remove(items_to_select, SP_GROUP(i->data)); - GSList *children = NULL; - sp_item_group_ungroup(SP_GROUP(i->data), &children, false); - items_to_select = g_slist_concat(children, items_to_select); + SPGroup *group = dynamic_cast<SPGroup *>(static_cast<SPObject *>(i->data)); + if (group) { + items_to_select = g_slist_remove(items_to_select, group); + GSList *children = NULL; + sp_item_group_ungroup(group, &children, false); + items_to_select = g_slist_concat(children, items_to_select); + } else { + g_assert_not_reached(); + } } g_slist_free(items_to_ungroup); @@ -4212,12 +4337,16 @@ void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) { static void itemtree_map(void (*f)(SPItem *, SPDesktop *), SPObject *root, SPDesktop *desktop) { // don't operate on layers - if (SP_IS_ITEM(root) && !desktop->isLayer(SP_ITEM(root))) { - f(SP_ITEM(root), desktop); + { + SPItem *item = dynamic_cast<SPItem *>(root); + if (item && !desktop->isLayer(item)) { + f(item, desktop); + } } for ( SPObject::SiblingIterator iter = root->firstChild() ; iter ; ++iter ) { //don't recurse into locked layers - if (!(SP_IS_ITEM(&*iter) && desktop->isLayer(SP_ITEM(&*iter)) && SP_ITEM(&*iter)->isLocked())) { + SPItem *item = dynamic_cast<SPItem *>(&*iter); + if (!(item && desktop->isLayer(item) && item->isLocked())) { itemtree_map(f, iter, desktop); } } diff --git a/src/seltrans.cpp b/src/seltrans.cpp index e15249f94..96c7fb49b 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -651,7 +651,7 @@ void Inkscape::SelTrans::_makeHandles() { for (int i = 0; i < NUMHANDS; i++) { SPSelTransTypeInfo info = handtypes[hands[i].type]; - knots[i] = new SPKnot(_desktop, info.tip); + knots[i] = new SPKnot(_desktop, _(info.tip)); knots[i]->setShape(SP_CTRL_SHAPE_BITMAP); knots[i]->setSize(13); diff --git a/src/sp-hatch-path.cpp b/src/sp-hatch-path.cpp index f7138fac2..8558b67f2 100644 --- a/src/sp-hatch-path.cpp +++ b/src/sp-hatch-path.cpp @@ -1,8 +1,11 @@ -/** @file +/** + * @file * SVG <hatchPath> implementation - *//* + */ +/* * Author: * Tomasz Boczkowski <penginsbacon@gmail.com> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2014 Tomasz Boczkowski * @@ -37,24 +40,31 @@ #include "sp-factory.h" namespace { -SPObject* createHatchPath() { + +SPObject* createHatchPath() +{ return new SPHatchPath(); } bool hatchRegistered = SPFactory::instance().registerObject("svg:hatchPath", createHatchPath); -} + +} // namespace SPHatchPath::SPHatchPath() - : _curve(NULL) - , _continuous(false) + : offset(), + _display(), + _curve(NULL), + _continuous(false) { offset.unset(); } -SPHatchPath::~SPHatchPath() { +SPHatchPath::~SPHatchPath() +{ } -void SPHatchPath::setCurve(SPCurve *new_curve, bool owner) { +void SPHatchPath::setCurve(SPCurve *new_curve, bool owner) +{ if (_curve) { _curve = _curve->unref(); } @@ -67,21 +77,23 @@ void SPHatchPath::setCurve(SPCurve *new_curve, bool owner) { } } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } -void SPHatchPath::build(SPDocument* doc, Inkscape::XML::Node* repr) { +void SPHatchPath::build(SPDocument* doc, Inkscape::XML::Node* repr) +{ SPObject::build(doc, repr); - this->readAttr("d"); - this->readAttr("offset"); - this->readAttr( "style" ); + readAttr("d"); + readAttr("offset"); + readAttr( "style" ); style->fill.setNone(); } -void SPHatchPath::release() { - for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { +void SPHatchPath::release() +{ + for (ViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { delete iter->arenaitem; iter->arenaitem = NULL; } @@ -89,7 +101,8 @@ void SPHatchPath::release() { SPObject::release(); } -void SPHatchPath::set(unsigned int key, const gchar* value) { +void SPHatchPath::set(unsigned int key, const gchar* value) +{ switch (key) { case SP_ATTR_D: if (value) { @@ -98,24 +111,24 @@ void SPHatchPath::set(unsigned int key, const gchar* value) { SPCurve *curve = new SPCurve(pv); if (curve) { - this->setCurve(curve, true); + setCurve(curve, true); curve->unref(); } } else { - this->setCurve(NULL, true); + setCurve(NULL, true); } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_OFFSET: offset.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; default: if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(this->style, this); + sp_style_read_from_object(style, this); requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPObject::set(key, value); @@ -125,41 +138,44 @@ void SPHatchPath::set(unsigned int key, const gchar* value) { } -void SPHatchPath::update(SPCtx* ctx, unsigned int flags) { - +void SPHatchPath::update(SPCtx* ctx, unsigned int flags) +{ if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { flags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; } if (flags & (SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { - if (this->style->stroke_width.unit == SP_CSS_UNIT_PERCENT) { + if (style->stroke_width.unit == SP_CSS_UNIT_PERCENT) { //TODO: Check specification - SPItemCtx *ictx = (SPItemCtx *) ctx; - double const aw = 1.0 / ictx->i2vp.descrim(); - this->style->stroke_width.computed = this->style->stroke_width.value * aw; + SPItemCtx *ictx = static_cast<SPItemCtx *>(ctx); + double const aw = (ictx) ? 1.0 / ictx->i2vp.descrim() : 1.0; + style->stroke_width.computed = style->stroke_width.value * aw; - for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { - iter->arenaitem->setStyle(this->style); + for (ViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { + iter->arenaitem->setStyle(style); } } } if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) { - for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { + for (ViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { _updateView(*iter); } } } -bool SPHatchPath::isValid() const { +bool SPHatchPath::isValid() const +{ if (_curve && (_repeatLength() <= 0)) { return false; + } else { + return true; } - return true; } -Inkscape::DrawingItem *SPHatchPath::show(Inkscape::Drawing &drawing, unsigned int key, Geom::OptInterval extents) { +Inkscape::DrawingItem *SPHatchPath::show(Inkscape::Drawing &drawing, unsigned int key, Geom::OptInterval extents) +{ Inkscape::DrawingShape *s = new Inkscape::DrawingShape(drawing); _display.push_front(View(s, key)); _display.front().extents = extents; @@ -169,8 +185,9 @@ Inkscape::DrawingItem *SPHatchPath::show(Inkscape::Drawing &drawing, unsigned in return s; } -void SPHatchPath::hide(unsigned int key) { - for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { +void SPHatchPath::hide(unsigned int key) +{ + for (ViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { if (iter->key == key) { delete iter->arenaitem; _display.erase(iter); @@ -181,8 +198,9 @@ void SPHatchPath::hide(unsigned int key) { g_assert_not_reached(); } -void SPHatchPath::setStripExtents(unsigned int key, Geom::OptInterval const &extents) { - for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { +void SPHatchPath::setStripExtents(unsigned int key, Geom::OptInterval const &extents) +{ + for (ViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { if (iter->key == key) { iter->extents = extents; break; @@ -190,18 +208,19 @@ void SPHatchPath::setStripExtents(unsigned int key, Geom::OptInterval const &ext } } -Geom::Interval SPHatchPath::bounds() const { +Geom::Interval SPHatchPath::bounds() const +{ Geom::OptRect bbox; Geom::Interval result; Geom::Affine transform = Geom::Translate(offset.computed, 0); - if (!this->_curve) { + if (!_curve) { SPCurve test_curve; test_curve.moveto(Geom::Point(0, 0)); test_curve.moveto(Geom::Point(0, 1)); bbox = bounds_exact_transformed(test_curve.get_pathvector(), transform); } else { - bbox = bounds_exact_transformed(this->_curve->get_pathvector(), transform); + bbox = bounds_exact_transformed(_curve->get_pathvector(), transform); } gdouble stroke_width = style->stroke_width.computed; @@ -210,8 +229,9 @@ Geom::Interval SPHatchPath::bounds() const { return result; } -SPCurve *SPHatchPath::calculateRenderCurve(unsigned key) const { - for (ConstViewIterator iter = _display.begin(); iter != _display.end(); iter++) { +SPCurve *SPHatchPath::calculateRenderCurve(unsigned key) const +{ + for (ConstViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { if (iter->key == key) { return _calculateRenderCurve(*iter); } @@ -220,31 +240,32 @@ SPCurve *SPHatchPath::calculateRenderCurve(unsigned key) const { return NULL; } -gdouble SPHatchPath::_repeatLength() const { - if (!_curve) { - return 0; - } +gdouble SPHatchPath::_repeatLength() const +{ + gdouble val = 0; - if (!_curve->last_point()) { - return 0; + if (_curve && _curve->last_point()) { + val = _curve->last_point()->y(); } - return _curve->last_point()->y(); + return val; } -void SPHatchPath::_updateView(View &view) { +void SPHatchPath::_updateView(View &view) +{ SPCurve *calculated_curve = _calculateRenderCurve(view); Geom::Affine offset_transform = Geom::Translate(offset.computed, 0); view.arenaitem->setTransform(offset_transform); style->fill.setNone(); - view.arenaitem->setStyle(this->style); + view.arenaitem->setStyle(style); view.arenaitem->setPath(calculated_curve); calculated_curve->unref(); } -SPCurve *SPHatchPath::_calculateRenderCurve(View const &view) const { +SPCurve *SPHatchPath::_calculateRenderCurve(View const &view) const +{ SPCurve *calculated_curve = new SPCurve; if (!view.extents) { @@ -265,7 +286,7 @@ SPCurve *SPHatchPath::_calculateRenderCurve(View const &view) const { segment->transform(Geom::Translate(0, initial_y)); Geom::Affine step_transform = Geom::Translate(0, repeatLength); - for (int i = 0; i < segment_cnt; i++) { + for (int i = 0; i < segment_cnt; ++i) { if (_continuous) { calculated_curve->append_continuous(segment, 0.0625); } else { @@ -281,7 +302,8 @@ SPCurve *SPHatchPath::_calculateRenderCurve(View const &view) const { } -void SPHatchPath::_readHatchPathVector(char const *str, Geom::PathVector &pathv, bool &continous_join) { +void SPHatchPath::_readHatchPathVector(char const *str, Geom::PathVector &pathv, bool &continous_join) +{ if (!str) { return; } @@ -314,8 +336,16 @@ void SPHatchPath::_readHatchPathVector(char const *str, Geom::PathVector &pathv, } SPHatchPath::View::View(Inkscape::DrawingShape *arenaitem, int key) - : arenaitem(arenaitem), key(key) + : arenaitem(arenaitem), + extents(), + key(key) +{ +} + +SPHatchPath::View::~View() { + // remember, do not delete arenaitem here + arenaitem = NULL; } diff --git a/src/sp-hatch-path.h b/src/sp-hatch-path.h index 57b3a8237..11fc274ec 100644 --- a/src/sp-hatch-path.h +++ b/src/sp-hatch-path.h @@ -1,8 +1,11 @@ -/** @file +/** + * @file * SVG <hatchPath> implementation - *//* + */ +/* * Author: * Tomasz Boczkowski <penginsbacon@gmail.com> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2014 Tomasz Boczkowski * @@ -26,43 +29,44 @@ class DrawingShape; } -#define SP_HATCH_PATH(obj) (dynamic_cast<SPHatchPath*>((SPObject*)obj)) -#define SP_IS_HATCH_PATH(obj) (dynamic_cast<const SPHatchPath*>((SPObject*)obj) != NULL) - class SPHatchPath : public SPObject { public: SPHatchPath(); - virtual ~SPHatchPath(); + virtual ~SPHatchPath(); - SVGLength offset; + SVGLength offset; - void setCurve(SPCurve *curve, bool owner); + void setCurve(SPCurve *curve, bool owner); bool isValid() const; Inkscape::DrawingItem *show(Inkscape::Drawing &drawing, unsigned int key, Geom::OptInterval extents); void hide(unsigned int key); - void setStripExtents(unsigned int key, Geom::OptInterval const &extents); - Geom::Interval bounds() const; + void setStripExtents(unsigned int key, Geom::OptInterval const &extents); + Geom::Interval bounds() const; - SPCurve *calculateRenderCurve(unsigned key) const; + SPCurve *calculateRenderCurve(unsigned key) const; protected: - virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void release(); - virtual void set(unsigned int key, const gchar* value); - virtual void update(SPCtx* ctx, unsigned int flags); + virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); + virtual void release(); + virtual void set(unsigned int key, const gchar* value); + virtual void update(SPCtx* ctx, unsigned int flags); private: - struct View { + class View { + public: View(Inkscape::DrawingShape *arenaitem, int key); //Do not delete arenaitem in destructor. + ~View(); + Inkscape::DrawingShape *arenaitem; Geom::OptInterval extents; unsigned int key; }; + typedef std::list<SPHatchPath::View>::iterator ViewIterator; typedef std::list<SPHatchPath::View>::const_iterator ConstViewIterator; std::list<View> _display; diff --git a/src/sp-hatch.cpp b/src/sp-hatch.cpp index b007fc846..4a8707e08 100644 --- a/src/sp-hatch.cpp +++ b/src/sp-hatch.cpp @@ -1,8 +1,11 @@ -/** @file +/** + * @file * SVG <hatch> implementation - *//* - * Author: + */ +/* + * Authors: * Tomasz Boczkowski <penginsbacon@gmail.com> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2014 Tomasz Boczkowski * @@ -35,65 +38,73 @@ #include "sp-factory.h" namespace { + SPObject* createHatch() { return new SPHatch(); } bool hatchRegistered = SPFactory::instance().registerObject("svg:hatch", createHatch); -} + +} // namespace SPHatch::SPHatch() - : SPPaintServer() + : SPPaintServer(), + href(), + ref(NULL), // avoiding 'this' in initializer list + _hatchUnits(UNITS_OBJECTBOUNDINGBOX), + _hatchUnits_set(false), + _hatchContentUnits(UNITS_USERSPACEONUSE), + _hatchContentUnits_set(false), + _hatchTransform(Geom::identity()), + _hatchTransform_set(false), + _x(), + _y(), + _pitch(), + _rotate(), + _modified_connection(), + _display() { - this->ref = new SPHatchReference(this); - this->ref->changedSignal().connect(sigc::mem_fun(this, &SPHatch::_onRefChanged)); - - this->_hatchUnits = UNITS_OBJECTBOUNDINGBOX; - this->_hatchUnits_set = false; + ref = new SPHatchReference(this); + ref->changedSignal().connect(sigc::mem_fun(this, &SPHatch::_onRefChanged)); - this->_hatchContentUnits = UNITS_USERSPACEONUSE; - this->_hatchContentUnits_set = false; - - this->_hatchTransform = Geom::identity(); - this->_hatchTransform_set = false; - - this->_x.unset(); - this->_y.unset(); - this->_pitch.unset(); - this->_rotate.unset(); + // TODO check that these should start already as unset: + _x.unset(); + _y.unset(); + _pitch.unset(); + _rotate.unset(); } SPHatch::~SPHatch() { } -void SPHatch::build(SPDocument* doc, Inkscape::XML::Node* repr) { +void SPHatch::build(SPDocument* doc, Inkscape::XML::Node* repr) +{ SPPaintServer::build(doc, repr); - this->readAttr("hatchUnits"); - this->readAttr("hatchContentUnits"); - this->readAttr("hatchTransform"); - this->readAttr("x"); - this->readAttr("y"); - this->readAttr("pitch"); - this->readAttr("rotate"); - this->readAttr("xlink:href"); - this->readAttr( "style" ); - - /* Register ourselves */ + readAttr("hatchUnits"); + readAttr("hatchContentUnits"); + readAttr("hatchTransform"); + readAttr("x"); + readAttr("y"); + readAttr("pitch"); + readAttr("rotate"); + readAttr("xlink:href"); + readAttr( "style" ); + + // Register ourselves doc->addResource("hatch", this); } -void SPHatch::release() { - if (this->document) { +void SPHatch::release() +{ + if (document) { // Unregister ourselves - this->document->removeResource("hatch", this); + document->removeResource("hatch", this); } - std::vector<SPHatchPath *> children; - hatchPaths(children); - for (ViewIterator view_iter = _display.begin(); view_iter != _display.end(); view_iter++) { - for (ChildIterator child_iter = children.begin(); child_iter != children.end(); - child_iter++) { + std::vector<SPHatchPath *> children(hatchPaths()); + for (ViewIterator view_iter = _display.begin(); view_iter != _display.end(); ++view_iter) { + for (ChildIterator child_iter = children.begin(); child_iter != children.end(); ++child_iter) { SPHatchPath *child = *child_iter; child->hide(view_iter->key); } @@ -101,20 +112,21 @@ void SPHatch::release() { view_iter->arenaitem = NULL; } - if (this->ref) { - this->_modified_connection.disconnect(); - this->ref->detach(); - delete this->ref; - this->ref = NULL; + if (ref) { + _modified_connection.disconnect(); + ref->detach(); + delete ref; + ref = NULL; } SPPaintServer::release(); } -void SPHatch::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) { +void SPHatch::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) +{ SPObject::child_added(child, ref); - SPHatchPath *path_child = SP_HATCH_PATH(this->document->getObjectByRepr(child)); + SPHatchPath *path_child = dynamic_cast<SPHatchPath *>(document->getObjectByRepr(child)); if (path_child) { for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { @@ -130,102 +142,103 @@ void SPHatch::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) //FIXME: notify all hatches that refer to this child set } -void SPHatch::set(unsigned int key, const gchar* value) { +void SPHatch::set(unsigned int key, const gchar* value) +{ switch (key) { case SP_ATTR_HATCHUNITS: if (value) { if (!strcmp(value, "userSpaceOnUse")) { - this->_hatchUnits = UNITS_USERSPACEONUSE; + _hatchUnits = UNITS_USERSPACEONUSE; } else { - this->_hatchUnits = UNITS_OBJECTBOUNDINGBOX; + _hatchUnits = UNITS_OBJECTBOUNDINGBOX; } - this->_hatchUnits_set = true; + _hatchUnits_set = true; } else { - this->_hatchUnits_set = false; + _hatchUnits_set = false; } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_HATCHCONTENTUNITS: if (value) { if (!strcmp(value, "userSpaceOnUse")) { - this->_hatchContentUnits = UNITS_USERSPACEONUSE; + _hatchContentUnits = UNITS_USERSPACEONUSE; } else { - this->_hatchContentUnits = UNITS_OBJECTBOUNDINGBOX; + _hatchContentUnits = UNITS_OBJECTBOUNDINGBOX; } - this->_hatchContentUnits_set = true; + _hatchContentUnits_set = true; } else { - this->_hatchContentUnits_set = false; + _hatchContentUnits_set = false; } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_HATCHTRANSFORM: { Geom::Affine t; if (value && sp_svg_transform_read(value, &t)) { - this->_hatchTransform = t; - this->_hatchTransform_set = true; + _hatchTransform = t; + _hatchTransform_set = true; } else { - this->_hatchTransform = Geom::identity(); - this->_hatchTransform_set = false; + _hatchTransform = Geom::identity(); + _hatchTransform_set = false; } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; } case SP_ATTR_X: - this->_x.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + _x.readOrUnset(value); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_Y: - this->_y.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + _y.readOrUnset(value); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_PITCH: - this->_pitch.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + _pitch.readOrUnset(value); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_ROTATE: - this->_rotate.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + _rotate.readOrUnset(value); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_XLINK_HREF: - if (value && this->href == value) { - /* Href unchanged, do nothing. */ + if (value && href == value) { + // Href unchanged, do nothing. } else { - this->href.clear(); + href.clear(); if (value) { // First, set the href field; it's only used in the "unchanged" check above. - this->href = value; + href = value; // Now do the attaching, which emits the changed signal. if (value) { try { - this->ref->attach(Inkscape::URI(value)); + ref->attach(Inkscape::URI(value)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); - this->ref->detach(); + ref->detach(); } } else { - this->ref->detach(); + ref->detach(); } } } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; default: if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(this->style, this); + sp_style_read_from_object(style, this); requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPPaintServer::set(key, value); @@ -234,43 +247,55 @@ void SPHatch::set(unsigned int key, const gchar* value) { } } -bool SPHatch::_hasHatchPatchChildren(SPHatch const *hatch) { - for (SPObject const *child = hatch->firstChild(); child; child = child->getNext() ) { - if (SP_IS_HATCH_PATH(child)) { - return true; +bool SPHatch::_hasHatchPatchChildren(SPHatch const *hatch) +{ + bool matched = false; + for (SPObject const *child = hatch->firstChild(); child && !matched; child = child->getNext() ) { + SPHatchPath const *hatchPath = dynamic_cast<SPHatchPath const *>(child); + if (hatchPath) { + matched = true; } } - return false; + return matched; } -void SPHatch::hatchPaths(std::vector<SPHatchPath*>& l) { +std::vector<SPHatchPath*> SPHatch::hatchPaths() +{ + std::vector<SPHatchPath*> list; SPHatch *src = chase_hrefs<SPHatch>(this, sigc::ptr_fun(&_hasHatchPatchChildren)); if (src) { for (SPObject *child = src->firstChild(); child; child = child->getNext()) { - if (SP_IS_HATCH_PATH(child)) { - l.push_back(SP_HATCH_PATH(child)); + SPHatchPath *hatchPath = dynamic_cast<SPHatchPath *>(child); + if (hatchPath) { + list.push_back(hatchPath); } } } + return list; } -void SPHatch::hatchPaths(std::vector<SPHatchPath const*>& l) const { +std::vector<SPHatchPath const*> SPHatch::hatchPaths() const +{ + std::vector<SPHatchPath const*> list; SPHatch const *src = chase_hrefs<SPHatch const>(this, sigc::ptr_fun(&_hasHatchPatchChildren)); if (src) { for (SPObject const *child = src->firstChild(); child; child = child->getNext()) { - if (SP_IS_HATCH_PATH(child)) { - l.push_back(SP_HATCH_PATH(child)); + SPHatchPath const *hatchPath = dynamic_cast<SPHatchPath const*>(child); + if (hatchPath) { + list.push_back(hatchPath); } } } + return list; } -/* TODO: ::remove_child and ::order_changed handles - see SPPattern */ +// TODO: ::remove_child and ::order_changed handles - see SPPattern -void SPHatch::update(SPCtx* ctx, unsigned int flags) { +void SPHatch::update(SPCtx* ctx, unsigned int flags) +{ typedef std::list<SPHatch::View>::iterator ViewIterator; if (flags & SP_OBJECT_MODIFIED_FLAG) { @@ -279,15 +304,14 @@ void SPHatch::update(SPCtx* ctx, unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - std::vector<SPHatchPath *> children; - hatchPaths(children); + std::vector<SPHatchPath *> children(hatchPaths()); - for (ChildIterator iter = children.begin(); iter != children.end(); iter++) { + for (ChildIterator iter = children.begin(); iter != children.end(); ++iter) { SPHatchPath* child = *iter; sp_object_ref(child, NULL); - for (ViewIterator view_iter = _display.begin(); view_iter != _display.end(); view_iter++) { + for (ViewIterator view_iter = _display.begin(); view_iter != _display.end(); ++view_iter) { Geom::OptInterval strip_extents = _calculateStripExtents(view_iter->bbox); child->setStripExtents(view_iter->key, strip_extents); } @@ -300,22 +324,22 @@ void SPHatch::update(SPCtx* ctx, unsigned int flags) { sp_object_unref(child, NULL); } - for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { + for (ViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { _updateView(*iter); } } -void SPHatch::modified(unsigned int flags) { +void SPHatch::modified(unsigned int flags) +{ if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } flags &= SP_OBJECT_MODIFIED_CASCADE; - std::vector<SPHatchPath *> children; - hatchPaths(children); + std::vector<SPHatchPath *> children(hatchPaths()); - for (ChildIterator iter = children.begin(); iter != children.end(); iter++) { + for (ChildIterator iter = children.begin(); iter != children.end(); ++iter) { SPObject *child = *iter; sp_object_ref(child, NULL); @@ -328,14 +352,16 @@ void SPHatch::modified(unsigned int flags) { } } -void SPHatch::_onRefChanged(SPObject *old_ref, SPObject *ref) { +void SPHatch::_onRefChanged(SPObject *old_ref, SPObject *ref) +{ typedef std::list<SPHatch::View>::iterator ViewIterator; if (old_ref) { _modified_connection.disconnect(); } - if (SP_IS_HATCH(ref)) { + SPHatch *hatch = dynamic_cast<SPHatch *>(ref); + if (hatch) { _modified_connection = ref->connectModified(sigc::mem_fun(this, &SPHatch::_onRefModified)); } @@ -344,24 +370,26 @@ void SPHatch::_onRefChanged(SPObject *old_ref, SPObject *ref) { SPHatch *new_shown = NULL; std::vector<SPHatchPath *> oldhatchPaths; std::vector<SPHatchPath *> newhatchPaths; - if (SP_IS_HATCH(old_ref)) { - old_shown = SP_HATCH(old_ref)->rootHatch(); - old_shown->hatchPaths(oldhatchPaths); + + SPHatch *old_hatch = dynamic_cast<SPHatch *>(old_ref); + if (old_hatch) { + old_shown = old_hatch->rootHatch(); + oldhatchPaths = old_shown->hatchPaths(); } - if (SP_IS_HATCH(ref)) { - new_shown = SP_HATCH(ref)->rootHatch(); - new_shown->hatchPaths(newhatchPaths); + if (hatch) { + new_shown = hatch->rootHatch(); + newhatchPaths = new_shown->hatchPaths(); } if (old_shown != new_shown) { - for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { + for (ViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { Geom::OptInterval extents = _calculateStripExtents(iter->bbox); - for (ChildIterator child_iter = oldhatchPaths.begin(); child_iter != oldhatchPaths.end(); child_iter++) { + for (ChildIterator child_iter = oldhatchPaths.begin(); child_iter != oldhatchPaths.end(); ++child_iter) { SPHatchPath *child = *child_iter; child->hide(iter->key); } - for (ChildIterator child_iter = newhatchPaths.begin(); child_iter != newhatchPaths.end(); child_iter++) { + for (ChildIterator child_iter = newhatchPaths.begin(); child_iter != newhatchPaths.end(); ++child_iter) { SPHatchPath *child = *child_iter; Inkscape::DrawingItem *cai = child->show(iter->arenaitem->drawing(), iter->key, extents); child->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -377,13 +405,15 @@ void SPHatch::_onRefChanged(SPObject *old_ref, SPObject *ref) { _onRefModified(ref, 0); } -void SPHatch::_onRefModified(SPObject */*ref*/, guint /*flags*/) { +void SPHatch::_onRefModified(SPObject */*ref*/, guint /*flags*/) +{ requestModified(SP_OBJECT_MODIFIED_FLAG); // Conditional to avoid causing infinite loop if there's a cycle in the href chain. } -SPHatch *SPHatch::rootHatch() { +SPHatch *SPHatch::rootHatch() +{ SPHatch *src = chase_hrefs<SPHatch>(this, sigc::ptr_fun(&_hasHatchPatchChildren)); return src ? src : this; // document is broken, we can't get to root; but at least we can return pat which is supposedly a valid hatch } @@ -391,101 +421,117 @@ SPHatch *SPHatch::rootHatch() { // Access functions that look up fields up the chain of referenced hatchs and return the first one which is set // FIXME: all of them must use chase_hrefs as children() and rootHatch() -SPHatch::HatchUnits SPHatch::hatchUnits() const { - for (SPHatch const *pat_i = this; pat_i != NULL; - pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->_hatchUnits_set) - return pat_i->_hatchUnits; +SPHatch::HatchUnits SPHatch::hatchUnits() const +{ + HatchUnits units = _hatchUnits; + for (SPHatch const *pat_i = this; pat_i; pat_i = (pat_i->ref) ? pat_i->ref->getObject() : NULL) { + if (pat_i->_hatchUnits_set) { + units = pat_i->_hatchUnits; + break; + } } - return _hatchUnits; + return units; } -SPHatch::HatchUnits SPHatch::hatchContentUnits() const { - for (SPHatch const *pat_i = this; pat_i != NULL; - pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->_hatchContentUnits_set) - return pat_i->_hatchContentUnits; +SPHatch::HatchUnits SPHatch::hatchContentUnits() const +{ + HatchUnits units = _hatchContentUnits; + for (SPHatch const *pat_i = this; pat_i; pat_i = (pat_i->ref) ? pat_i->ref->getObject() : NULL) { + if (pat_i->_hatchContentUnits_set) { + units = pat_i->_hatchContentUnits; + break; + } } - return _hatchContentUnits; + return units; } -Geom::Affine const &SPHatch::hatchTransform() const { - for (SPHatch const *pat_i = this; pat_i != NULL; - pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->_hatchTransform_set) +Geom::Affine const &SPHatch::hatchTransform() const +{ + for (SPHatch const *pat_i = this; pat_i; pat_i = (pat_i->ref) ? pat_i->ref->getObject() : NULL) { + if (pat_i->_hatchTransform_set) { return pat_i->_hatchTransform; + } } return _hatchTransform; } -gdouble SPHatch::x() const { - for (SPHatch const *pat_i = this; pat_i != NULL; - pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->_x._set) - return pat_i->_x.computed; +gdouble SPHatch::x() const +{ + gdouble val = 0; + for (SPHatch const *pat_i = this; pat_i; pat_i = (pat_i->ref) ? pat_i->ref->getObject() : NULL) { + if (pat_i->_x._set) { + val = pat_i->_x.computed; + break; + } } - return 0; + return val; } -gdouble SPHatch::y() const { - for (SPHatch const *pat_i = this; pat_i != NULL; - pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->_y._set) - return pat_i->_y.computed; +gdouble SPHatch::y() const +{ + gdouble val = 0; + for (SPHatch const *pat_i = this; pat_i; pat_i = (pat_i->ref) ? pat_i->ref->getObject() : NULL) { + if (pat_i->_y._set) { + val = pat_i->_y.computed; + break; + } } - return 0; + return val; } -gdouble SPHatch::pitch() const { - for (SPHatch const *pat_i = this; pat_i != NULL; - pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->_pitch._set) - return pat_i->_pitch.computed; +gdouble SPHatch::pitch() const +{ + gdouble val = 0; + for (SPHatch const *pat_i = this; pat_i; pat_i = (pat_i->ref) ? pat_i->ref->getObject() : NULL) { + if (pat_i->_pitch._set) { + val = pat_i->_pitch.computed; + break; + } } - return 0; + return val; } -gdouble SPHatch::rotate() const { - for (SPHatch const *pat_i = this; pat_i != NULL; - pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->_rotate._set) - return pat_i->_rotate.computed; +gdouble SPHatch::rotate() const +{ + gdouble val = 0; + for (SPHatch const *pat_i = this; pat_i; pat_i = (pat_i->ref) ? pat_i->ref->getObject() : NULL) { + if (pat_i->_rotate._set) { + val = pat_i->_rotate.computed; + break; + } } - return 0; + return val; } -bool SPHatch::isValid() const { - double strip_pitch = pitch(); - if (strip_pitch <= 0) { - return false; - } - - std::vector<SPHatchPath const *> children; - hatchPaths(children); - if (children.empty()) { - return false; - } - for (ConstChildIterator iter = children.begin(); iter != children.end(); iter++) { - SPHatchPath const *child = *iter; - if (!child->isValid()) { - return false; +bool SPHatch::isValid() const +{ + bool valid = false; + + if (pitch() > 0) { + std::vector<SPHatchPath const *> children(hatchPaths()); + if (!children.empty()) { + valid = true; + for (ConstChildIterator iter = children.begin(); (iter != children.end()) && valid; ++iter) { + SPHatchPath const *child = *iter; + valid = child->isValid(); + } } } - return true; + return valid; } -Inkscape::DrawingPattern *SPHatch::show(Inkscape::Drawing &drawing, unsigned int key, Geom::OptRect bbox) { +Inkscape::DrawingPattern *SPHatch::show(Inkscape::Drawing &drawing, unsigned int key, Geom::OptRect bbox) +{ Inkscape::DrawingPattern *ai = new Inkscape::DrawingPattern(drawing); //TODO: set some debug flag to see DrawingPattern _display.push_front(View(ai, key)); _display.front().bbox = bbox; - std::vector<SPHatchPath *> children; - hatchPaths(children); + std::vector<SPHatchPath *> children(hatchPaths()); Geom::OptInterval extents = _calculateStripExtents(bbox); - for (ChildIterator iter = children.begin(); iter != children.end(); iter++) { + for (ChildIterator iter = children.begin(); iter != children.end(); ++iter) { SPHatchPath *child = *iter; Inkscape::DrawingItem *cai = child->show(drawing, key, extents); if (cai) { @@ -499,16 +545,16 @@ Inkscape::DrawingPattern *SPHatch::show(Inkscape::Drawing &drawing, unsigned int return ai; } -void SPHatch::hide(unsigned int key) { - std::vector<SPHatchPath *> children; - hatchPaths(children); +void SPHatch::hide(unsigned int key) +{ + std::vector<SPHatchPath *> children(hatchPaths()); - for (ChildIterator iter = children.begin(); iter != children.end(); iter++) { + for (ChildIterator iter = children.begin(); iter != children.end(); ++iter) { SPHatchPath *child = *iter; child->hide(key); } - for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { + for (ViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { if (iter->key == key) { delete iter->arenaitem; _display.erase(iter); @@ -520,12 +566,12 @@ void SPHatch::hide(unsigned int key) { } -Geom::Interval SPHatch::bounds() const { +Geom::Interval SPHatch::bounds() const +{ Geom::Interval result; - std::vector<SPHatchPath const *> children; - hatchPaths(children); + std::vector<SPHatchPath const *> children(hatchPaths()); - for (ConstChildIterator iter = children.begin(); iter != children.end(); iter++) { + for (ConstChildIterator iter = children.begin(); iter != children.end(); ++iter) { SPHatchPath const *child = *iter; if (result.extent() == 0) { result = child->bounds(); @@ -536,9 +582,10 @@ Geom::Interval SPHatch::bounds() const { return result; } -SPHatch::RenderInfo SPHatch::calculateRenderInfo(unsigned key) const { +SPHatch::RenderInfo SPHatch::calculateRenderInfo(unsigned key) const +{ RenderInfo info; - for (ConstViewIterator iter = _display.begin(); iter != _display.end(); iter++) { + for (ConstViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { if (iter->key == key) { return _calculateRenderInfo(*iter); } @@ -547,7 +594,8 @@ SPHatch::RenderInfo SPHatch::calculateRenderInfo(unsigned key) const { return info; } -void SPHatch::_updateView(View &view) { +void SPHatch::_updateView(View &view) +{ RenderInfo info = _calculateRenderInfo(view); //The rendering of hatch overflow is implemented by repeated drawing //of hatch paths over one strip. Within each iteration paths are moved by pitch value. @@ -558,93 +606,94 @@ void SPHatch::_updateView(View &view) { view.arenaitem->setChildTransform(info.child_transform); view.arenaitem->setPatternToUserTransform(info.pattern_to_user_transform); view.arenaitem->setTileRect(info.tile_rect); - view.arenaitem->setStyle(this->style); + view.arenaitem->setStyle(style); view.arenaitem->setOverflow(info.overflow_initial_transform, info.overflow_steps, - info.overflow_step_transform); + info.overflow_step_transform); } -SPHatch::RenderInfo SPHatch::_calculateRenderInfo(View const &view) const { +SPHatch::RenderInfo SPHatch::_calculateRenderInfo(View const &view) const +{ RenderInfo info; Geom::OptInterval extents = _calculateStripExtents(view.bbox); - if (!extents) { - return info; - } - - double tile_x = x(); - double tile_y = y(); - double tile_width = pitch(); - double tile_height = extents->max() - extents->min(); - double tile_rotate = rotate(); - double tile_render_y = extents->min(); - - if (view.bbox && (hatchUnits() == UNITS_OBJECTBOUNDINGBOX)) { - tile_x *= view.bbox->width(); - tile_y *= view.bbox->height(); - tile_width *= view.bbox->width(); - tile_height *= view.bbox->height(); - tile_render_y *= view.bbox->height(); - } - - // Pattern size in hatch space - Geom::Rect hatch_tile = Geom::Rect::from_xywh(0, tile_render_y, tile_width, tile_height); - // Content to bbox - Geom::Affine content2ps; - if (view.bbox && (hatchContentUnits() == UNITS_OBJECTBOUNDINGBOX)) { - content2ps = Geom::Affine(view.bbox->width(), 0.0, 0.0, view.bbox->height(), 0, 0); - } - - // Tile (hatch space) to user. - Geom::Affine ps2user = Geom::Translate(tile_x, tile_y) * Geom::Rotate::from_degrees(tile_rotate) * hatchTransform(); - - info.child_transform = content2ps; - info.pattern_to_user_transform = ps2user; - info.tile_rect = hatch_tile; - - if (style->overflow.computed == SP_CSS_OVERFLOW_VISIBLE) { - Geom::Interval bounds = this->bounds(); - gdouble pitch = this->pitch(); - gdouble overflow_right_strip = floor(bounds.max() / pitch) * pitch; - info.overflow_steps = ceil((overflow_right_strip - bounds.min()) / pitch) + 1; - info.overflow_step_transform = Geom::Translate(pitch, 0.0); - info.overflow_initial_transform = Geom::Translate(-overflow_right_strip, 0.0); - } else { - info.overflow_steps = 1; + if (extents) { + double tile_x = x(); + double tile_y = y(); + double tile_width = pitch(); + double tile_height = extents->max() - extents->min(); + double tile_rotate = rotate(); + double tile_render_y = extents->min(); + + if (view.bbox && (hatchUnits() == UNITS_OBJECTBOUNDINGBOX)) { + tile_x *= view.bbox->width(); + tile_y *= view.bbox->height(); + tile_width *= view.bbox->width(); + tile_height *= view.bbox->height(); + tile_render_y *= view.bbox->height(); + } + + // Pattern size in hatch space + Geom::Rect hatch_tile = Geom::Rect::from_xywh(0, tile_render_y, tile_width, tile_height); + + // Content to bbox + Geom::Affine content2ps; + if (view.bbox && (hatchContentUnits() == UNITS_OBJECTBOUNDINGBOX)) { + content2ps = Geom::Affine(view.bbox->width(), 0.0, 0.0, view.bbox->height(), 0, 0); + } + + // Tile (hatch space) to user. + Geom::Affine ps2user = Geom::Translate(tile_x, tile_y) * Geom::Rotate::from_degrees(tile_rotate) * hatchTransform(); + + info.child_transform = content2ps; + info.pattern_to_user_transform = ps2user; + info.tile_rect = hatch_tile; + + if (style->overflow.computed == SP_CSS_OVERFLOW_VISIBLE) { + Geom::Interval bounds = this->bounds(); + gdouble pitch = this->pitch(); + gdouble overflow_right_strip = floor(bounds.max() / pitch) * pitch; + info.overflow_steps = ceil((overflow_right_strip - bounds.min()) / pitch) + 1; + info.overflow_step_transform = Geom::Translate(pitch, 0.0); + info.overflow_initial_transform = Geom::Translate(-overflow_right_strip, 0.0); + } else { + info.overflow_steps = 1; + } } return info; } //calculates strip extents in content space -Geom::OptInterval SPHatch::_calculateStripExtents(Geom::OptRect bbox) const { +Geom::OptInterval SPHatch::_calculateStripExtents(Geom::OptRect const &bbox) const +{ if (!bbox || (bbox->area() == 0)) { return Geom::OptInterval(); - } - - double tile_x = x(); - double tile_y = y(); - double tile_rotate = rotate(); - - Geom::Affine ps2user = Geom::Translate(tile_x, tile_y) * Geom::Rotate::from_degrees(tile_rotate) * hatchTransform(); - Geom::Affine user2ps = ps2user.inverse(); - - Geom::Interval extents; - for (int i = 0; i < 4; i++) { - Geom::Point corner = bbox->corner(i); - Geom::Point corner_ps = corner * user2ps; - if (i == 0 || corner_ps.y() < extents.min()) { - extents.setMin(corner_ps.y()); + } else { + double tile_x = x(); + double tile_y = y(); + double tile_rotate = rotate(); + + Geom::Affine ps2user = Geom::Translate(tile_x, tile_y) * Geom::Rotate::from_degrees(tile_rotate) * hatchTransform(); + Geom::Affine user2ps = ps2user.inverse(); + + Geom::Interval extents; + for (int i = 0; i < 4; ++i) { + Geom::Point corner = bbox->corner(i); + Geom::Point corner_ps = corner * user2ps; + if (i == 0 || corner_ps.y() < extents.min()) { + extents.setMin(corner_ps.y()); + } + if (i == 0 || corner_ps.y() > extents.max()) { + extents.setMax(corner_ps.y()); + } } - if (i == 0 || corner_ps.y() > extents.max()) { - extents.setMax(corner_ps.y()); + + if (hatchUnits() == UNITS_OBJECTBOUNDINGBOX) { + extents /= bbox->height(); } - } - if (hatchUnits() == UNITS_OBJECTBOUNDINGBOX) { - extents /= bbox->height(); + return extents; } - - return extents; } cairo_pattern_t* SPHatch::pattern_new(cairo_t * /*base_ct*/, Geom::OptRect const &/*bbox*/, double /*opacity*/) @@ -654,8 +703,9 @@ cairo_pattern_t* SPHatch::pattern_new(cairo_t * /*base_ct*/, Geom::OptRect const return cairo_pattern_create_rgb(0.5, 0.5, 1.0); } -void SPHatch::setBBox(unsigned int key, Geom::OptRect const &bbox) { - for (ViewIterator iter = _display.begin(); iter != _display.end(); iter++) { +void SPHatch::setBBox(unsigned int key, Geom::OptRect const &bbox) +{ + for (ViewIterator iter = _display.begin(); iter != _display.end(); ++iter) { if (iter->key == key) { iter->bbox = bbox; break; @@ -663,10 +713,37 @@ void SPHatch::setBBox(unsigned int key, Geom::OptRect const &bbox) { } } +// + +SPHatch::RenderInfo::RenderInfo() + : child_transform(), + pattern_to_user_transform(), + tile_rect(), + overflow_steps(0), + overflow_step_transform(), + overflow_initial_transform() +{ +} + +SPHatch::RenderInfo::~RenderInfo() +{ +} + +// + SPHatch::View::View(Inkscape::DrawingPattern *arenaitem, int key) - : arenaitem(arenaitem), key(key) + : arenaitem(arenaitem), + bbox(), + key(key) { } + +SPHatch::View::~View() +{ + // remember, do not delete arenaitem here + arenaitem = NULL; +} + /* Local Variables: mode:c++ diff --git a/src/sp-hatch.h b/src/sp-hatch.h index dc6ee0add..5004a611f 100644 --- a/src/sp-hatch.h +++ b/src/sp-hatch.h @@ -1,8 +1,11 @@ -/** @file +/** + * @file * SVG <hatch> implementation - *//* - * Author: + */ +/* + * Authors: * Tomasz Boczkowski <penginsbacon@gmail.com> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2014 Tomasz Boczkowski * @@ -38,9 +41,6 @@ class Node; } } -#define SP_HATCH(obj) (dynamic_cast<SPHatch*>((SPObject*)obj)) -#define SP_IS_HATCH(obj) (dynamic_cast<const SPHatch*>((SPObject*)obj) != NULL) - class SPHatch : public SPPaintServer { public: enum HatchUnits { @@ -48,7 +48,11 @@ public: UNITS_OBJECTBOUNDINGBOX }; - struct RenderInfo { + class RenderInfo { + public: + RenderInfo(); + ~RenderInfo(); + Geom::Affine child_transform; Geom::Affine pattern_to_user_transform; Geom::Rect tile_rect; @@ -59,10 +63,10 @@ public: }; SPHatch(); - virtual ~SPHatch(); + virtual ~SPHatch(); - /* Reference (href) */ - Glib::ustring href; + // Reference (href) + Glib::ustring href; SPHatchReference *ref; gdouble x() const; @@ -74,32 +78,35 @@ public: Geom::Affine const &hatchTransform() const; SPHatch *rootHatch(); //TODO: const - void hatchPaths(std::vector<SPHatchPath*>& l); - void hatchPaths(std::vector<SPHatchPath const *>& l) const; + std::vector<SPHatchPath *> hatchPaths(); + std::vector<SPHatchPath const *> hatchPaths() const; bool isValid() const; Inkscape::DrawingPattern *show(Inkscape::Drawing &drawing, unsigned int key, Geom::OptRect bbox); void hide(unsigned int key); - virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity); + virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity); - RenderInfo calculateRenderInfo(unsigned key) const; - Geom::Interval bounds() const; - void setBBox(unsigned int key, Geom::OptRect const &bbox); + RenderInfo calculateRenderInfo(unsigned key) const; + Geom::Interval bounds() const; + void setBBox(unsigned int key, Geom::OptRect const &bbox); protected: - virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void release(); - virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); - virtual void set(unsigned int key, const gchar* value); - virtual void update(SPCtx* ctx, unsigned int flags); - virtual void modified(unsigned int flags); + virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); + virtual void release(); + virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); + virtual void set(unsigned int key, const gchar* value); + virtual void update(SPCtx* ctx, unsigned int flags); + virtual void modified(unsigned int flags); private: - struct View { + class View { + public: View(Inkscape::DrawingPattern *arenaitem, int key); //Do not delete arenaitem in destructor. + ~View(); + Inkscape::DrawingPattern *arenaitem; Geom::OptRect bbox; unsigned int key; @@ -114,28 +121,30 @@ private: void _updateView(View &view); RenderInfo _calculateRenderInfo(View const &view) const; - Geom::OptInterval _calculateStripExtents(Geom::OptRect bbox) const; + Geom::OptInterval _calculateStripExtents(Geom::OptRect const &bbox) const; - /** - Gets called when the hatch is reattached to another <hatch> - */ - void _onRefChanged(SPObject *old_ref, SPObject *ref); + /** + * Gets called when the hatch is reattached to another <hatch> + */ + void _onRefChanged(SPObject *old_ref, SPObject *ref); - /** - Gets called when the referenced <hatch> is changed - */ - void _onRefModified(SPObject *ref, guint flags); + /** + * Gets called when the referenced <hatch> is changed + */ + void _onRefModified(SPObject *ref, guint flags); - /* patternUnits and patternContentUnits attribute */ + // patternUnits and patternContentUnits attribute HatchUnits _hatchUnits : 1; bool _hatchUnits_set : 1; HatchUnits _hatchContentUnits : 1; bool _hatchContentUnits_set : 1; - /* hatchTransform attribute */ + + // hatchTransform attribute Geom::Affine _hatchTransform; bool _hatchTransform_set : 1; - /* Strip */ + + // Strip SVGLength _x; SVGLength _y; SVGLength _pitch; @@ -149,14 +158,17 @@ private: class SPHatchReference : public Inkscape::URIReference { public: - SPHatchReference (SPObject *obj) : URIReference(obj) {} + SPHatchReference (SPObject *obj) + : URIReference(obj) + {} + SPHatch *getObject() const { return reinterpret_cast<SPHatch *>(URIReference::getObject()); } protected: virtual bool _acceptObject(SPObject *obj) const { - return SP_IS_HATCH (obj); + return dynamic_cast<SPHatch *>(obj) != NULL; } }; diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index b2af3842e..613ace5c1 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -96,14 +96,14 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) if (last_child && last_child->getRepr() == child) { // optimization for the common special case where the child is being added at the end - SPObject *ochild = last_child; - if ( SP_IS_ITEM(ochild) ) { + SPItem *item = dynamic_cast<SPItem *>(last_child); + if ( item ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; Inkscape::DrawingItem *ac; for (v = this->display; v != NULL; v = v->next) { - ac = SP_ITEM (ochild)->invoke_show (v->arenaitem->drawing(), v->key, v->flags); + ac = item->invoke_show (v->arenaitem->drawing(), v->key, v->flags); if (ac) { v->arenaitem->appendChild(ac); @@ -111,16 +111,16 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) } } } else { // general case - SPObject *ochild = this->get_child_by_repr(child); - if ( ochild && SP_IS_ITEM(ochild) ) { + SPItem *item = dynamic_cast<SPItem *>(get_child_by_repr(child)); + if ( item ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; Inkscape::DrawingItem *ac; - unsigned position = SP_ITEM(ochild)->pos_in_parent(); + unsigned position = item->pos_in_parent(); for (v = this->display; v != NULL; v = v->next) { - ac = SP_ITEM (ochild)->invoke_show (v->arenaitem->drawing(), v->key, v->flags); + ac = item->invoke_show (v->arenaitem->drawing(), v->key, v->flags); if (ac) { v->arenaitem->prependChild(ac); @@ -145,12 +145,12 @@ void SPGroup::order_changed (Inkscape::XML::Node *child, Inkscape::XML::Node *ol { SPLPEItem::order_changed(child, old_ref, new_ref); - SPObject *ochild = this->get_child_by_repr(child); - if ( ochild && SP_IS_ITEM(ochild) ) { + SPItem *item = dynamic_cast<SPItem *>(get_child_by_repr(child)); + if ( item ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; - unsigned position = SP_ITEM(ochild)->pos_in_parent(); - for ( v = SP_ITEM (ochild)->display ; v != NULL ; v = v->next ) { + unsigned position = item->pos_in_parent(); + for ( v = item->display ; v != NULL ; v = v->next ) { v->arenaitem->setZOrder(position); } } @@ -177,10 +177,10 @@ void SPGroup::update(SPCtx *ctx, unsigned int flags) { l = g_slist_remove (l, child); if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - if (SP_IS_ITEM (child)) { - SPItem const &chi = *SP_ITEM(child); - cctx.i2doc = chi.transform * ictx->i2doc; - cctx.i2vp = chi.transform * ictx->i2vp; + SPItem *item = dynamic_cast<SPItem *>(child); + if (item) { + cctx.i2doc = item->transform * ictx->i2doc; + cctx.i2vp = item->transform * ictx->i2vp; child->updateDisplay((SPCtx *)&cctx, childflags); } else { child->updateDisplay(ctx, childflags); @@ -230,14 +230,11 @@ void SPGroup::modified(guint flags) { } Inkscape::XML::Node* SPGroup::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPGroup* object = this; - SPGroup *group = SP_GROUP(object); - if (flags & SP_OBJECT_WRITE_BUILD) { - GSList *l; + GSList *l = NULL; if (!repr) { - if (SP_IS_SWITCH(object)) { + if (dynamic_cast<SPSwitch *>(this)) { repr = xml_doc->createElement("svg:switch"); } else { repr = xml_doc->createElement("svg:g"); @@ -246,8 +243,8 @@ Inkscape::XML::Node* SPGroup::write(Inkscape::XML::Document *xml_doc, Inkscape:: l = NULL; - for (SPObject *child = object->firstChild(); child; child = child->getNext() ) { - if ( !SP_IS_TITLE(child) && !SP_IS_DESC(child) ) { + for (SPObject *child = firstChild(); child; child = child->getNext() ) { + if ( !dynamic_cast<SPTitle *>(child) && !dynamic_cast<SPDesc *>(child) ) { Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); if (crepr) { @@ -262,8 +259,8 @@ Inkscape::XML::Node* SPGroup::write(Inkscape::XML::Document *xml_doc, Inkscape:: l = g_slist_remove (l, l->data); } } else { - for (SPObject *child = object->firstChild() ; child ; child = child->getNext() ) { - if ( !SP_IS_TITLE(child) && !SP_IS_DESC(child) ) { + for (SPObject *child = firstChild() ; child ; child = child->getNext() ) { + if ( !dynamic_cast<SPTitle *>(child) && !dynamic_cast<SPDesc *>(child) ) { child->updateRepr(flags); } } @@ -271,9 +268,9 @@ Inkscape::XML::Node* SPGroup::write(Inkscape::XML::Document *xml_doc, Inkscape:: if ( flags & SP_OBJECT_WRITE_EXT ) { const char *value; - if ( group->_layer_mode == SPGroup::LAYER ) { + if ( _layer_mode == SPGroup::LAYER ) { value = "layer"; - } else if ( group->_layer_mode == SPGroup::MASK_HELPER ) { + } else if ( _layer_mode == SPGroup::MASK_HELPER ) { value = "maskhelper"; } else if ( flags & SP_OBJECT_WRITE_ALL ) { value = "group"; @@ -293,16 +290,16 @@ Geom::OptRect SPGroup::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox { Geom::OptRect bbox; - // CPPIFY: replace this const_cast later + // TODO CPPIFY: replace this const_cast later GSList *l = const_cast<SPGroup*>(this)->childList(false, SPObject::ActionBBox); while (l) { SPObject *o = SP_OBJECT (l->data); - if (SP_IS_ITEM(o) && !SP_ITEM(o)->isHidden()) { - SPItem *child = SP_ITEM(o); - Geom::Affine const ct(child->transform * transform); - bbox |= child->bounds(bboxtype, ct); + SPItem *item = dynamic_cast<SPItem *>(o); + if (item && !item->isHidden()) { + Geom::Affine const ct(item->transform * transform); + bbox |= item->bounds(bboxtype, ct); } l = g_slist_remove (l, o); @@ -317,8 +314,9 @@ void SPGroup::print(SPPrintContext *ctx) { while (l) { SPObject *o = SP_OBJECT (l->data); - if (SP_IS_ITEM(o)) { - SP_ITEM(o)->invoke_print (ctx); + SPItem *item = dynamic_cast<SPItem *>(o); + if (item) { + item->invoke_print(ctx); } l = g_slist_remove (l, o); @@ -365,16 +363,14 @@ Inkscape::DrawingItem *SPGroup::show (Inkscape::Drawing &drawing, unsigned int k } void SPGroup::hide (unsigned int key) { - SPItem * child; - GSList *l = g_slist_reverse(this->childList(false, SPObject::ActionShow)); while (l) { SPObject *o = SP_OBJECT (l->data); - if (SP_IS_ITEM (o)) { - child = SP_ITEM (o); - child->invoke_hide (key); + SPItem *item = dynamic_cast<SPItem *>(o); + if (item) { + item->invoke_hide(key); } l = g_slist_remove (l, o); @@ -387,8 +383,9 @@ void SPGroup::hide (unsigned int key) { void SPGroup::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) const { for ( SPObject const *o = this->firstChild(); o; o = o->getNext() ) { - if (SP_IS_ITEM(o)) { - SP_ITEM(o)->getSnappoints(p, snapprefs); + SPItem const *item = dynamic_cast<SPItem const *>(o); + if (item) { + item->getSnappoints(p, snapprefs); } } } @@ -398,14 +395,12 @@ void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) { g_return_if_fail (group != NULL); - g_return_if_fail (SP_IS_GROUP (group)); SPDocument *doc = group->document; SPRoot *root = doc->getRoot(); SPObject *defs = root->defs; - SPItem *gitem = group; - Inkscape::XML::Node *grepr = gitem->getRepr(); + Inkscape::XML::Node *grepr = group->getRepr(); g_return_if_fail (!strcmp (grepr->name(), "svg:g") || !strcmp (grepr->name(), "svg:a") @@ -413,33 +408,34 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) || !strcmp (grepr->name(), "svg:svg")); // this converts the gradient/pattern fill/stroke on the group, if any, to userSpaceOnUse - gitem->adjust_paint_recursive (Geom::identity(), Geom::identity(), false); + group->adjust_paint_recursive (Geom::identity(), Geom::identity(), false); - SPItem *pitem = SP_ITEM(gitem->parent); + SPItem *pitem = dynamic_cast<SPItem *>(group->parent); + g_assert(pitem); Inkscape::XML::Node *prepr = pitem->getRepr(); - if (SP_IS_BOX3D(gitem)) { - group = box3d_convert_to_group(SP_BOX3D(gitem)); - gitem = group; - } + { + SPBox3D *box = dynamic_cast<SPBox3D *>(group); + if (box) { + group = box3d_convert_to_group(box); + } + } - SP_LPE_ITEM(group)->removeAllPathEffects(false); + group->removeAllPathEffects(false); /* Step 1 - generate lists of children objects */ GSList *items = NULL; GSList *objects = NULL; for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM (child)) { - - SPItem *citem = SP_ITEM (child); - + SPItem *citem = dynamic_cast<SPItem *>(child); + if (citem) { /* Merging of style */ // this converts the gradient/pattern fill/stroke, if any, to userSpaceOnUse; we need to do // it here _before_ the new transform is set, so as to use the pre-transform bbox citem->adjust_paint_recursive (Geom::identity(), Geom::identity(), false); - sp_style_merge_from_dying_parent(child->style, gitem->style); + sp_style_merge_from_dying_parent(child->style, group->style); /* * fixme: We currently make no allowance for the case where child is cloned * and the group has any style settings. @@ -468,20 +464,21 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) // Merging transform Geom::Affine ctrans; - Geom::Affine const g(gitem->transform); - if (SP_IS_USE(citem) && SP_USE(citem)->get_original() && - SP_USE(citem)->get_original()->parent == SP_OBJECT(group)) { + Geom::Affine const g(group->transform); + SPUse *useitem = dynamic_cast<SPUse *>(citem); + if (useitem && useitem->get_original() && + useitem->get_original()->parent == dynamic_cast<SPObject *>(group)) { // make sure a clone's effective transform is the same as was under group ctrans = g.inverse() * citem->transform * g; } else { // We should not apply the group's transformation to both a linked offset AND to its source - if (SP_IS_OFFSET(citem)) { // Do we have an offset at hand (whether it's dynamic or linked)? - SPItem *source = sp_offset_get_source(SP_OFFSET(citem)); + if (dynamic_cast<SPOffset *>(citem)) { // Do we have an offset at hand (whether it's dynamic or linked)? + SPItem *source = sp_offset_get_source(dynamic_cast<SPOffset *>(citem)); // When dealing with a chain of linked offsets, the transformation of an offset will be // tied to the transformation of the top-most source, not to any of the intermediate // offsets. So let's find the top-most source - while (source != NULL && SP_IS_OFFSET(source)) { - source = sp_offset_get_source(SP_OFFSET(source)); + while (source != NULL && dynamic_cast<SPOffset *>(source)) { + source = sp_offset_get_source(dynamic_cast<SPOffset *>(source)); } if (source != NULL && // If true then we must be dealing with a linked offset ... group->isAncestorOf(source) == false) { // ... of which the source is not in the same group @@ -548,10 +545,14 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) // fill in the children list if non-null SPItem *item = static_cast<SPItem *>(doc->getObjectByRepr(repr)); - item->doWriteTransform(repr, item->transform, NULL, false); + if (item) { + item->doWriteTransform(repr, item->transform, NULL, false); + } else { + g_assert_not_reached(); + } Inkscape::GC::release(repr); - if (children && SP_IS_ITEM(item)) { + if (children && item) { *children = g_slist_prepend(*children, item); } @@ -570,12 +571,11 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) GSList *sp_item_group_item_list(SPGroup * group) { g_return_val_if_fail(group != NULL, NULL); - g_return_val_if_fail(SP_IS_GROUP(group), NULL); GSList *s = NULL; for (SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { - if ( SP_IS_ITEM(o) ) { + if ( dynamic_cast<SPItem *>(o) ) { s = g_slist_prepend(s, o); } } @@ -649,8 +649,9 @@ void SPGroup::translateChildItems(Geom::Translate const &tr) { if ( hasChildren() ) { for (SPObject *o = firstChild() ; o ; o = o->getNext() ) { - if ( SP_IS_ITEM(o) ) { - sp_item_move_rel(reinterpret_cast<SPItem *>(o), tr); + SPItem *item = dynamic_cast<SPItem *>(o); + if ( item ) { + sp_item_move_rel(item, tr); } } } @@ -661,8 +662,10 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo { if ( hasChildren() ) { for (SPObject *o = firstChild() ; o ; o = o->getNext() ) { - if ( SP_IS_ITEM(o) ) { - if (SP_IS_GROUP(o) && !SP_IS_BOX3D(o)) { + SPItem *item = dynamic_cast<SPItem *>(o); + if ( item ) { + SPGroup *group = dynamic_cast<SPGroup *>(item); + if (group && !dynamic_cast<SPBox3D *>(item)) { /* Using recursion breaks clipping because transforms are applied in coordinates for draws but nothing in defs is changed instead change the transform on the entire group, and the transform @@ -673,7 +676,6 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo */ if(noRecurse) { // used for EMF import - SPItem *item = SP_ITEM(o); Geom::Translate const s(p); Geom::Affine final = s.inverse() * sc * s; Geom::Affine tAff = item->i2dt_affine() * final; @@ -689,30 +691,29 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo item->doWriteTransform(item->getRepr(), tAff, NULL, true); } else { // used for other import - SPItem *item = NULL; - if (SP_ITEM(o)->clip_ref->getObject()) { - item = SP_ITEM(SP_ITEM(o)->clip_ref->getObject()->firstChild()); + SPItem *subItem = NULL; + if (item->clip_ref->getObject()) { + subItem = dynamic_cast<SPItem *>(item->clip_ref->getObject()->firstChild()); } - if (item != NULL) { + if (subItem != NULL) { Geom::Affine tdoc2dt = Geom::Scale(1, -1) * Geom::Translate(p); // re-create doc2dt() - Geom::Affine ti2doc = SP_ITEM(o)->i2doc_affine(); - item->set_i2d_affine(ti2doc * sc * ti2doc.inverse() * tdoc2dt); - item->doWriteTransform(item->getRepr(), item->transform, NULL, true); + Geom::Affine ti2doc = item->i2doc_affine(); + subItem->set_i2d_affine(ti2doc * sc * ti2doc.inverse() * tdoc2dt); + subItem->doWriteTransform(subItem->getRepr(), subItem->transform, NULL, true); } - item = NULL; - if (SP_ITEM(o)->mask_ref->getObject()) { - item = SP_ITEM(SP_ITEM(o)->mask_ref->getObject()->firstChild()); + subItem = NULL; + if (item->mask_ref->getObject()) { + subItem = dynamic_cast<SPItem *>(item->mask_ref->getObject()->firstChild()); } - if (item != NULL) { + if (subItem != NULL) { Geom::Affine tdoc2dt = Geom::Scale(1, -1) * Geom::Translate(p); // re-create doc2dt() - Geom::Affine ti2doc = SP_ITEM(o)->i2doc_affine(); - item->set_i2d_affine(ti2doc * sc * ti2doc.inverse() * tdoc2dt); - item->doWriteTransform(item->getRepr(), item->transform, NULL, true); + Geom::Affine ti2doc = item->i2doc_affine(); + subItem->set_i2d_affine(ti2doc * sc * ti2doc.inverse() * tdoc2dt); + subItem->doWriteTransform(item->getRepr(), item->transform, NULL, true); } - SP_GROUP(o)->scaleChildItemsRec(sc, p, false); + group->scaleChildItemsRec(sc, p, false); } } else { - SPItem *item = SP_ITEM(o); Geom::OptRect bbox = item->desktopVisualBounds(); if (bbox) { // Scale item @@ -720,24 +721,33 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo Geom::Affine final = s.inverse() * sc * s; gchar const *conn_type = NULL; - if (SP_IS_TEXT_TEXTPATH(item)) { - SP_TEXT(item)->optimizeTextpathText(); - } else if (SP_IS_FLOWTEXT(item)) { - SP_FLOWTEXT(item)->optimizeScaledText(); - } else if (SP_IS_BOX3D(item)) { - // Force recalculation from perspective - box3d_position_set(SP_BOX3D(item)); - } else if (item->getAttribute("inkscape:connector-type") != NULL - && (item->getAttribute("inkscape:connection-start") == NULL - || item->getAttribute("inkscape:connection-end") == NULL)) { - // Remove and store connector type for transform if disconnected - conn_type = item->getAttribute("inkscape:connector-type"); - item->removeAttribute("inkscape:connector-type"); + SPText *textItem = dynamic_cast<SPText *>(item); + bool isTextTextpath = textItem && textItem->firstChild() && dynamic_cast<SPTextPath *>(textItem->firstChild()); + if (isTextTextpath) { + textItem->optimizeTextpathText(); + } else { + SPFlowtext *flowText = dynamic_cast<SPFlowtext *>(item); + if (flowText) { + flowText->optimizeScaledText(); + } else { + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box) { + // Force recalculation from perspective + box3d_position_set(box); + } else if (item->getAttribute("inkscape:connector-type") != NULL + && (item->getAttribute("inkscape:connection-start") == NULL + || item->getAttribute("inkscape:connection-end") == NULL)) { + // Remove and store connector type for transform if disconnected + conn_type = item->getAttribute("inkscape:connector-type"); + item->removeAttribute("inkscape:connector-type"); + } + } } - if (SP_IS_PERSP3D(item)) { - persp3d_apply_affine_transformation(SP_PERSP3D(item), final); - } else if (SP_IS_TEXT_TEXTPATH(item) && !item->transform.isIdentity()) { + Persp3D *persp = dynamic_cast<Persp3D *>(item); + if (persp) { + persp3d_apply_affine_transformation(persp, final); + } else if (isTextTextpath && !item->transform.isIdentity()) { // Save and reset current transform Geom::Affine tmp(item->transform); item->transform = Geom::Affine(); @@ -748,7 +758,7 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo tmp[4] *= sc[0]; tmp[5] *= sc[1]; item->doWriteTransform(item->getRepr(), tmp, NULL, true); - } else if (SP_IS_USE(item)) { + } else if (dynamic_cast<SPUse *>(item)) { // calculate the matrix we need to apply to the clone // to cancel its induced transform from its original Geom::Affine move = final.inverse() * item->transform * final; @@ -776,7 +786,7 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo gint SPGroup::getItemCount() const { gint len = 0; for (SPObject const *o = this->firstChild() ; o ; o = o->getNext() ) { - if (SP_IS_ITEM(o)) { + if (dynamic_cast<SPItem const *>(o)) { len++; } } @@ -786,12 +796,11 @@ gint SPGroup::getItemCount() const { void SPGroup::_showChildren (Inkscape::Drawing &drawing, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags) { Inkscape::DrawingItem *ac = NULL; - SPItem * child = NULL; GSList *l = g_slist_reverse(this->childList(false, SPObject::ActionShow)); while (l) { SPObject *o = SP_OBJECT (l->data); - if (SP_IS_ITEM (o)) { - child = SP_ITEM (o); + SPItem * child = dynamic_cast<SPItem *>(o); + if (child) { ac = child->invoke_show (drawing, key, flags); if (ac) { ai->appendChild(ac); @@ -811,8 +820,9 @@ void SPGroup::update_patheffect(bool write) { for ( GSList const *iter = item_list; iter; iter = iter->next ) { SPObject *subitem = static_cast<SPObject *>(iter->data); - if (SP_IS_LPE_ITEM(subitem)) { - ((SPLPEItem*)subitem)->update_patheffect(write); + SPLPEItem *lpeItem = dynamic_cast<SPLPEItem *>(subitem); + if (lpeItem) { + lpeItem->update_patheffect(write); } } @@ -833,40 +843,45 @@ void SPGroup::update_patheffect(bool write) { static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) { - GSList const *item_list = sp_item_group_item_list(SP_GROUP(group)); + GSList const *item_list = sp_item_group_item_list(group); for ( GSList const *iter = item_list; iter; iter = iter->next ) { SPObject *subitem = static_cast<SPObject *>(iter->data); - if (SP_IS_GROUP(subitem)) { - sp_group_perform_patheffect(SP_GROUP(subitem), topgroup, write); - } else if (SP_IS_SHAPE(subitem)) { - SPCurve * c = NULL; + SPGroup *subGroup = dynamic_cast<SPGroup *>(subitem); + if (subGroup) { + sp_group_perform_patheffect(subGroup, topgroup, write); + } else { + SPShape *subShape = dynamic_cast<SPShape *>(subitem); + if (subShape) { + SPCurve * c = NULL; - if (SP_IS_PATH(subitem)) { - c = SP_PATH(subitem)->get_original_curve(); - } else { - c = SP_SHAPE(subitem)->getCurve(); - } + SPPath *subPath = dynamic_cast<SPPath *>(subShape); + if (subPath) { + c = subPath->get_original_curve(); + } else { + c = subShape->getCurve(); + } - // only run LPEs when the shape has a curve defined - if (c) { - c->transform(i2anc_affine(subitem, topgroup)); - SP_LPE_ITEM(topgroup)->performPathEffect(c); - c->transform(i2anc_affine(subitem, topgroup).inverse()); - SP_SHAPE(subitem)->setCurve(c, TRUE); - - if (write) { - Inkscape::XML::Node *repr = subitem->getRepr(); - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); + // only run LPEs when the shape has a curve defined + if (c) { + c->transform(i2anc_affine(subitem, topgroup)); + topgroup->performPathEffect(c); + c->transform(i2anc_affine(subitem, topgroup).inverse()); + subShape->setCurve(c, TRUE); + + if (write) { + Inkscape::XML::Node *repr = subitem->getRepr(); + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); #ifdef GROUP_VERBOSE -g_message("sp_group_perform_patheffect writes 'd' attribute"); + g_message("sp_group_perform_patheffect writes 'd' attribute"); #endif - g_free(str); - } + g_free(str); + } - c->unref(); + c->unref(); + } } } } diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 2259088ba..8b7e735e0 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -95,12 +95,12 @@ void SPShape::release() { if (this->_marker[i]) { for (SPItemView *v = this->display; v != NULL; v = v->next) { - sp_marker_hide ((SPMarker *) this->_marker[i], v->arenaitem->key() + i); + sp_marker_hide(_marker[i], v->arenaitem->key() + i); } this->_release_connect[i].disconnect(); this->_modified_connect[i].disconnect(); - this->_marker[i] = sp_object_hunref (this->_marker[i], this); + _marker[i] = static_cast<SPMarker *>(sp_object_hunref(_marker[i], this)); } } @@ -170,10 +170,10 @@ void SPShape::update(SPCtx* ctx, guint flags) { } for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { - if (this->_marker[i]) { - sp_marker_show_dimension ((SPMarker *) this->_marker[i], - v->arenaitem->key() + i, - this->numberOfMarkers (i)); + if (_marker[i]) { + sp_marker_show_dimension(_marker[i], + v->arenaitem->key() + i, + numberOfMarkers(i)); } } } @@ -290,12 +290,12 @@ sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) if ( shape->_marker[i] ) { Geom::Affine m_auto = m; // Reverse start marker if necessary. - if (SP_MARKER(shape->_marker[i])->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { + if (shape->_marker[i]->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { m_auto = Geom::Rotate::from_degrees( 180.0 ) * m; } - sp_marker_show_instance ((SPMarker* ) shape->_marker[i], ai, - ai->key() + i, counter[i], m_auto, - shape->style->stroke_width.computed); + sp_marker_show_instance(shape->_marker[i], ai, + ai->key() + i, counter[i], m_auto, + shape->style->stroke_width.computed); counter[i]++; } } @@ -311,9 +311,9 @@ sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) Geom::Affine const m (sp_shape_marker_get_transform_at_start(path_it->front())); for (int i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID if ( shape->_marker[i] ) { - sp_marker_show_instance ((SPMarker* ) shape->_marker[i], ai, - ai->key() + i, counter[i], m, - shape->style->stroke_width.computed); + sp_marker_show_instance(shape->_marker[i], ai, + ai->key() + i, counter[i], m, + shape->style->stroke_width.computed); counter[i]++; } } @@ -331,9 +331,9 @@ sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) Geom::Affine const m (sp_shape_marker_get_transform(*curve_it1, *curve_it2)); for (int i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID if (shape->_marker[i]) { - sp_marker_show_instance ((SPMarker* ) shape->_marker[i], ai, - ai->key() + i, counter[i], m, - shape->style->stroke_width.computed); + sp_marker_show_instance(shape->_marker[i], ai, + ai->key() + i, counter[i], m, + shape->style->stroke_width.computed); counter[i]++; } } @@ -348,9 +348,9 @@ sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) Geom::Affine const m = sp_shape_marker_get_transform_at_end(lastcurve); for (int i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID if (shape->_marker[i]) { - sp_marker_show_instance ((SPMarker* ) shape->_marker[i], ai, - ai->key() + i, counter[i], m, - shape->style->stroke_width.computed); + sp_marker_show_instance(shape->_marker[i], ai, + ai->key() + i, counter[i], m, + shape->style->stroke_width.computed); counter[i]++; } } @@ -372,9 +372,9 @@ sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) for (int i = 0; i < 4; i += 3) { // SP_MARKER_LOC and SP_MARKER_LOC_END if (shape->_marker[i]) { - sp_marker_show_instance ((SPMarker* ) shape->_marker[i], ai, - ai->key() + i, counter[i], m, - shape->style->stroke_width.computed); + sp_marker_show_instance(shape->_marker[i], ai, + ai->key() + i, counter[i], m, + shape->style->stroke_width.computed); counter[i]++; } } @@ -424,26 +424,25 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox // START marker for (unsigned i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START if ( this->_marker[i] ) { - SPMarker* marker = SP_MARKER (this->_marker[i]); - SPItem* marker_item = sp_item_first_item_child( marker ); + SPItem* marker_item = sp_item_first_item_child( _marker[i] ); if (marker_item) { Geom::Affine tr(sp_shape_marker_get_transform_at_start(pathv.begin()->front())); - if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { + if (_marker[i]->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { // Reverse start marker if necessary tr = Geom::Rotate::from_degrees( 180.0 ) * tr; - } else if (marker->orient_mode == MARKER_ORIENT_ANGLE) { + } else if (_marker[i]->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(_marker[i]->orient) * Geom::Translate(transl); } - if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { + if (_marker[i]->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { tr = Geom::Scale(this->style->stroke_width.computed) * tr; } // total marker transform - tr = marker_item->transform * marker->c2p * tr * transform; + tr = marker_item->transform * _marker[i]->c2p * tr * transform; // get bbox of the marker with that transform bbox |= marker_item->visualBounds(tr); @@ -457,7 +456,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox continue; } - SPMarker* marker = SP_MARKER (this->_marker[i]); + SPMarker* marker = _marker[i]; SPItem* marker_item = sp_item_first_item_child( marker ); if ( !marker_item ) { @@ -495,7 +494,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox * Loop to end_default (so including closing segment), because when a path is closed, * there should be a midpoint marker between last segment and closing straight line segment */ - SPMarker* marker = SP_MARKER (this->_marker[i]); + SPMarker* marker = _marker[i]; SPItem* marker_item = sp_item_first_item_child( marker ); if (marker_item) { @@ -541,8 +540,8 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox // END marker for (unsigned i = 0; i < 4; i += 3) { // SP_MARKER_LOC and SP_MARKER_LOC_END - if ( this->_marker[i] ) { - SPMarker* marker = SP_MARKER (this->_marker[i]); + if ( _marker[i] ) { + SPMarker* marker = _marker[i]; SPItem* marker_item = sp_item_first_item_child( marker ); if (marker_item) { @@ -739,10 +738,10 @@ Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /* } for (int i = 0; i < SP_MARKER_LOC_QTY; i++) { - if (this->_marker[i]) { - sp_marker_show_dimension ((SPMarker *) this->_marker[i], - s->key() + i, - this->numberOfMarkers (i)); + if (_marker[i]) { + sp_marker_show_dimension(_marker[i], + s->key() + i, + numberOfMarkers(i)); } } @@ -757,17 +756,17 @@ Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /* * Sets style, path, and paintbox. Updates marker views, including dimensions. */ void SPShape::hide(unsigned int key) { - for (int i=0; i<SP_MARKER_LOC_QTY; i++) { - if (this->_marker[i]) { - for (SPItemView* v = this->display; v != NULL; v = v->next) { - if (key == v->key) { - sp_marker_hide ((SPMarker *) this->_marker[i], v->arenaitem->key() + i); - } - } - } - } + for (int i = 0; i < SP_MARKER_LOC_QTY; ++i) { + if (_marker[i]) { + for (SPItemView* v = display; v != NULL; v = v->next) { + if (key == v->key) { + sp_marker_hide(_marker[i], v->arenaitem->key() + i); + } + } + } + } - //SPLPEItem::onHide(key); + //SPLPEItem::onHide(key); } /** @@ -782,7 +781,7 @@ int SPShape::hasMarkers() const // Ignore markers for objects which are inside markers themselves. for (SPObject *parent = this->parent; parent != NULL; parent = parent->parent) { - if(SP_IS_MARKER(parent)) { + if (dynamic_cast<SPMarker *>(parent)) { return 0; } } @@ -860,22 +859,20 @@ int SPShape::numberOfMarkers(int type) const { static void sp_shape_marker_release (SPObject *marker, SPShape *shape) { - SPItem *item; - int i; + SPItem *item = dynamic_cast<SPItem *>(shape); + g_return_if_fail(item != NULL); - item = (SPItem *) shape; - - for (i = 0; i < SP_MARKER_LOC_QTY; i++) { + for (int i = 0; i < SP_MARKER_LOC_QTY; i++) { if (marker == shape->_marker[i]) { SPItemView *v; /* Hide marker */ for (v = item->display; v != NULL; v = v->next) { - sp_marker_hide ((SPMarker *) (shape->_marker[i]), v->arenaitem->key() + i); + sp_marker_hide(shape->_marker[i], v->arenaitem->key() + i); } /* Detach marker */ shape->_release_connect[i].disconnect(); shape->_modified_connect[i].disconnect(); - shape->_marker[i] = sp_object_hunref (shape->_marker[i], item); + shape->_marker[i] = static_cast<SPMarker *>(sp_object_hunref(shape->_marker[i], item)); } } } @@ -900,15 +897,16 @@ sp_shape_marker_modified (SPObject */*marker*/, guint /*flags*/, SPItem */*item* void sp_shape_set_marker (SPObject *object, unsigned int key, const gchar *value) { - SPItem *item = (SPItem *) object; - SPShape *shape = (SPShape *) object; + SPShape *shape = dynamic_cast<SPShape *>(object); + g_return_if_fail(shape != NULL); if (key > SP_MARKER_LOC_END) { return; } SPObject *mrk = sp_css_uri_reference_resolve(object->document, value); - if (mrk != shape->_marker[key]) { + SPMarker *marker = dynamic_cast<SPMarker *>(mrk); + if (marker != shape->_marker[key]) { if (shape->_marker[key]) { SPItemView *v; @@ -917,18 +915,18 @@ sp_shape_set_marker (SPObject *object, unsigned int key, const gchar *value) shape->_modified_connect[key].disconnect(); /* Hide marker */ - for (v = item->display; v != NULL; v = v->next) { - sp_marker_hide ((SPMarker *) (shape->_marker[key]), - v->arenaitem->key() + key); + for (v = shape->display; v != NULL; v = v->next) { + sp_marker_hide(shape->_marker[key], + v->arenaitem->key() + key); } /* Unref marker */ - shape->_marker[key] = sp_object_hunref (shape->_marker[key], object); + shape->_marker[key] = static_cast<SPMarker *>(sp_object_hunref(shape->_marker[key], object)); } - if (SP_IS_MARKER (mrk)) { - shape->_marker[key] = sp_object_href (mrk, object); - shape->_release_connect[key] = mrk->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_shape_marker_release), shape)); - shape->_modified_connect[key] = mrk->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_shape_marker_modified), shape)); + if (marker) { + shape->_marker[key] = static_cast<SPMarker *>(sp_object_href(marker, object)); + shape->_release_connect[key] = marker->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_shape_marker_release), shape)); + shape->_modified_connect[key] = marker->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_shape_marker_modified), shape)); } } } diff --git a/src/sp-shape.h b/src/sp-shape.h index da8e4c007..fe9d03275 100644 --- a/src/sp-shape.h +++ b/src/sp-shape.h @@ -28,6 +28,7 @@ #define SP_SHAPE_WRITE_PATH (1 << 2) class SPDesktop; +class SPMarker; namespace Inkscape { class DrawingItem; } /** @@ -51,7 +52,7 @@ public: // temporarily public, until SPPath is properly classed, etc. SPCurve *_curve; public: - SPObject *_marker[SP_MARKER_LOC_QTY]; + SPMarker *_marker[SP_MARKER_LOC_QTY]; sigc::connection _release_connect [SP_MARKER_LOC_QTY]; sigc::connection _modified_connect [SP_MARKER_LOC_QTY]; diff --git a/src/transf_mat_3x4.cpp b/src/transf_mat_3x4.cpp index 20eee658c..05d0e9d6d 100644 --- a/src/transf_mat_3x4.cpp +++ b/src/transf_mat_3x4.cpp @@ -62,11 +62,9 @@ TransfMat3x4::image (Pt3 const &point) { Pt3 TransfMat3x4::preimage (Geom::Point const &pt, double coord, Proj::Axis axis) { - double x[4]; - double v[3]; - v[0] = pt[Geom::X]; - v[1] = pt[Geom::Y]; - v[2] = 1.0; + const double init_val = std::numeric_limits<double>::quiet_NaN(); + double x[4] = { init_val, init_val, init_val, init_val }; + double v[3] = { pt[Geom::X], pt[Geom::Y], 1.0 }; int index = (int) axis; SysEq::SolutionKind sol = SysEq::gaussjord_solve<3,4>(tmat, x, v, index, coord, true); diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 40500cf15..931a295d8 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -54,6 +54,7 @@ #include <2geom/transforms.h> #include "box3d.h" #include "gradient-drag.h" +#include "sp-marker.h" #include "sp-item.h" #include "sp-item-transform.h" // for sp_item_scale_rel, used in _pasteSize #include "sp-path.h" @@ -505,12 +506,15 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a // resize each object in the selection if (separately) { for (GSList *i = const_cast<GSList*>(selection->itemList()) ; i ; i = i->next) { - SPItem *item = SP_ITEM(i->data); - Geom::OptRect obj_size = item->desktopVisualBounds(); - if ( !obj_size ) { - continue; + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); + if (item) { + Geom::OptRect obj_size = item->desktopVisualBounds(); + if ( obj_size ) { + sp_item_scale_rel(item, _getScale(desktop, min, max, *obj_size, apply_x, apply_y)); + } + } else { + g_assert_not_reached(); } - sp_item_scale_rel(item, _getScale(desktop, min, max, *obj_size, apply_x, apply_y)); } } // resize the selection as a whole @@ -640,7 +644,12 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) GSList const *items = selection->itemList(); // copy the defs used by all items for (GSList *i = const_cast<GSList *>(items) ; i != NULL ; i = i->next) { - _copyUsedDefs(SP_ITEM (i->data)); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); + if (item) { + _copyUsedDefs(item); + } else { + g_assert_not_reached(); + } } // copy the representation of the items @@ -648,36 +657,38 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) sorted_items = g_slist_sort(sorted_items, (GCompareFunc) sp_object_compare_position); for (GSList *i = sorted_items ; i ; i = i->next) { - if (!SP_IS_ITEM(i->data)) { - continue; + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); + if (item) { + Inkscape::XML::Node *obj = item->getRepr(); + Inkscape::XML::Node *obj_copy = _copyNode(obj, _doc, _root); + + // copy complete inherited style + SPCSSAttr *css = sp_repr_css_attr_inherited(obj, "style"); + sp_repr_css_set(obj_copy, css, "style"); + sp_repr_css_attr_unref(css); + + // write the complete accumulated transform passed to us + // (we're dealing with unattached representations, so we write to their attributes + // instead of using sp_item_set_transform) + gchar *transform_str = sp_svg_transform_write(item->i2doc_affine()); + obj_copy->setAttribute("transform", transform_str); + g_free(transform_str); } - Inkscape::XML::Node *obj = reinterpret_cast<SPObject *>(i->data)->getRepr(); - Inkscape::XML::Node *obj_copy = _copyNode(obj, _doc, _root); - - // copy complete inherited style - SPCSSAttr *css = sp_repr_css_attr_inherited(obj, "style"); - sp_repr_css_set(obj_copy, css, "style"); - sp_repr_css_attr_unref(css); - - // write the complete accumulated transform passed to us - // (we're dealing with unattached representations, so we write to their attributes - // instead of using sp_item_set_transform) - gchar *transform_str = sp_svg_transform_write(SP_ITEM(i->data)->i2doc_affine()); - obj_copy->setAttribute("transform", transform_str); - g_free(transform_str); } // copy style for Paste Style action if (sorted_items) { - if (SP_IS_ITEM(sorted_items->data)) { - SPCSSAttr *style = take_style_from_item((SPItem *) sorted_items->data); + SPObject *object = static_cast<SPObject *>(sorted_items->data); + SPItem *item = dynamic_cast<SPItem *>(object); + if (item) { + SPCSSAttr *style = take_style_from_item(item); sp_repr_css_set(_clipnode, style, "style"); sp_repr_css_attr_unref(style); } // copy path effect from the first path - if (SP_IS_OBJECT(sorted_items->data)) { - gchar const *effect = reinterpret_cast<SPObject *>(sorted_items->data)->getRepr()->attribute("inkscape:path-effect"); + if (object) { + gchar const *effect =object->getRepr()->attribute("inkscape:path-effect"); if (effect) { _clipnode->setAttribute("inkscape:path-effect", effect); } @@ -704,35 +715,38 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) if (style && (style->fill.isPaintserver())) { SPPaintServer *server = item->style->getFillPaintServer(); - if ( SP_IS_LINEARGRADIENT(server) || SP_IS_RADIALGRADIENT(server) ) { - _copyGradient(SP_GRADIENT(server)); + if ( dynamic_cast<SPLinearGradient *>(server) || dynamic_cast<SPRadialGradient *>(server) ) { + _copyGradient(dynamic_cast<SPGradient *>(server)); } - if ( SP_IS_PATTERN(server) ) { - _copyPattern(SP_PATTERN(server)); + SPPattern *pattern = dynamic_cast<SPPattern *>(server); + if ( pattern ) { + _copyPattern(pattern); } } if (style && (style->stroke.isPaintserver())) { SPPaintServer *server = item->style->getStrokePaintServer(); - if ( SP_IS_LINEARGRADIENT(server) || SP_IS_RADIALGRADIENT(server) ) { - _copyGradient(SP_GRADIENT(server)); + if ( dynamic_cast<SPLinearGradient *>(server) || dynamic_cast<SPRadialGradient *>(server) ) { + _copyGradient(dynamic_cast<SPGradient *>(server)); } - if ( SP_IS_PATTERN(server) ) { - _copyPattern(SP_PATTERN(server)); + SPPattern *pattern = dynamic_cast<SPPattern *>(server); + if ( pattern ) { + _copyPattern(pattern); } } // For shapes, copy all of the shape's markers - if (SP_IS_SHAPE(item)) { - SPShape *shape = SP_SHAPE (item); + SPShape *shape = dynamic_cast<SPShape *>(item); + if (shape) { for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { if (shape->_marker[i]) { _copyNode(shape->_marker[i]->getRepr(), _doc, _defs); } } } + // For lpe items, copy lpe stack if applicable - if (SP_IS_LPE_ITEM(item)) { - SPLPEItem *lpeitem = SP_LPE_ITEM (item); + SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); + if (lpeitem) { if (lpeitem->hasPathEffect()) { for (PathEffectList::iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->path_effect_list->end(); ++it) { @@ -743,14 +757,24 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) } } } + // For 3D boxes, copy perspectives - if (SP_IS_BOX3D(item)) { - _copyNode(box3d_get_perspective(SP_BOX3D(item))->getRepr(), _doc, _defs); + { + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box) { + _copyNode(box3d_get_perspective(box)->getRepr(), _doc, _defs); + } } + // Copy text paths - if (SP_IS_TEXT_TEXTPATH(item)) { - _copyTextPath(SP_TEXTPATH(item->firstChild())); + { + SPText *text = dynamic_cast<SPText *>(item); + SPTextPath *textpath = (text) ? dynamic_cast<SPTextPath *>(text->firstChild()) : NULL; + if (textpath) { + _copyTextPath(textpath); + } } + // Copy clipping objects if (item->clip_ref){ if (item->clip_ref->getObject()) { @@ -764,8 +788,9 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) _copyNode(mask->getRepr(), _doc, _defs); // recurse into the mask for its gradients etc. for (SPObject *o = mask->children ; o != NULL ; o = o->next) { - if (SP_IS_ITEM(o)) { - _copyUsedDefs(SP_ITEM(o)); + SPItem *childItem = dynamic_cast<SPItem *>(o); + if (childItem) { + _copyUsedDefs(childItem); } } } @@ -774,15 +799,16 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) // Copy filters if (style->getFilter()) { SPObject *filter = style->getFilter(); - if (SP_IS_FILTER(filter)) { + if (dynamic_cast<SPFilter *>(filter)) { _copyNode(filter->getRepr(), _doc, _defs); } } // recurse for (SPObject *o = item->children ; o != NULL ; o = o->next) { - if (SP_IS_ITEM(o)) { - _copyUsedDefs(SP_ITEM(o)); + SPItem *childItem = dynamic_cast<SPItem *>(o); + if (childItem) { + _copyUsedDefs(childItem); } } } @@ -817,10 +843,10 @@ void ClipboardManagerImpl::_copyPattern(SPPattern *pattern) // items in the pattern may also use gradients and other patterns, so recurse for ( SPObject *child = pattern->firstChild() ; child ; child = child->getNext() ) { - if (!SP_IS_ITEM (child)) { - continue; + SPItem *childItem = dynamic_cast<SPItem *>(child); + if (childItem) { + _copyUsedDefs(childItem); } - _copyUsedDefs(SP_ITEM(child)); } if (pattern->ref){ pattern = pattern->ref->getObject(); @@ -939,13 +965,13 @@ void ClipboardManagerImpl::_applyPathEffect(SPItem *item, gchar const *effectsta if ( item == NULL ) { return; } - if ( SP_IS_RECT(item) ) { + if ( dynamic_cast<SPRect *>(item) ) { return; } - if (SP_IS_LPE_ITEM(item)) + SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); + if (lpeitem) { - SPLPEItem *lpeitem = SP_LPE_ITEM(item); // for each effect in the stack, check if we need to fork it before adding it to the item lpeitem->forkPathEffectsIfNecessary(1); diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 7212fa372..50b35ca2f 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -452,13 +452,13 @@ void AboutBox::initStrings() { */ gchar const *allTranslators = "3ARRANO.com <3arrano@3arrano.com>, 2005.\n" -"Adib Taraben <theadib@gmail.com>, 2004.\n" +"Adib Taraben <theadib@gmail.com>, 2004-2014.\n" "Alan Monfort <alan.monfort@free.fr>, 2009-2010.\n" "Alastair McKinstry <mckinstry@computer.org>, 2000.\n" "Aleksandar UroÅ¡ević <urke@users.sourceforge.net>, 2004-2006.\n" "Alessio Frusciante <algol@firenze.linux.it>, 2002, 2003.\n" "Alexander Shopov <ash@contact.bg>, 2006.\n" -"Alexandre Prokoudine <alexandre.prokoudine@gmail.com>, 2005, 2010-2013.\n" +"Alexandre Prokoudine <alexandre.prokoudine@gmail.com>, 2005, 2010-2014.\n" "Alexey Remizov <alexey@remizov.pp.ru>, 2004.\n" "Ali Ghanavatian <ghanvatian.ali@gmail.com>, 2010.\n" "Ãlvaro Lopes <alvieboy@alvie.com>, 2001, 2002.\n" @@ -503,7 +503,7 @@ void AboutBox::initStrings() { "Hleb Valoshka <375gnu@gmail.com>, 2008-2009.\n" "Hizkuntza Politikarako Sailburuordetza <hizkpol@ej-gv.es>, 2005.\n" "Ilia Penev <lichopicho@gmail.com>, 2006.\n" -"Ivan Masár <helix84@centrum.sk>, 2006-2010. \n" +"Ivan Masár <helix84@centrum.sk>, 2006-2014. \n" "Ivan ŘihoÅ¡ek <irihosek@seznam.cz>, 2014.\n" "Iñaki Larrañaga <dooteo@euskalgnu.org>, 2006.\n" "JÄnis Eisaks <jancs@dv.lv>, 2012-2014.\n" @@ -537,7 +537,7 @@ void AboutBox::initStrings() { "Mahesh subedi <submanesh@hotmail.com>, 2006.\n" "Martin Srebotnjak, <miles@filmsi.net>, 2005, 2010.\n" "Masatake YAMATO <jet@gyve.org>, 2002.\n" -"Masato Hashimoto <cabezon.hashimoto@gmail.com>, 2009-2012.\n" +"Masato Hashimoto <cabezon.hashimoto@gmail.com>, 2009-2014.\n" "Matiphas <matiphas _a_ free _point_ fr>, 2004-2006.\n" "Mattias Hultgren <mattias_hultgren@tele2.se>, 2005, 2006.\n" "Maxim Dziumanenko <mvd@mylinux.com.ua>, 2004.\n" @@ -553,7 +553,7 @@ void AboutBox::initStrings() { "PrzemysÅ‚aw Loesch <p_loesch@poczta.onet.pl>, 2005.\n" "Quico Llach <quico@softcatala.org>, 2000. Traducció sodipodi.\n" "Raymond Ostertag <raymond@linuxgraphic.org>, 2002, 2003.\n" -"Riku Leino <tsoots@gmail.com>, 2006.\n" +"Riku Leino <tsoots@gmail.com>, 2006-2011.\n" "Rune Rønde Laursen <runerl@skjoldhoej.dk>, 2006.\n" "Ruud Steltenpool <svg@steltenpower.com>, 2006.\n" "Serdar Soytetir <sendirom@gmail.com>, 2005.\n" @@ -569,9 +569,11 @@ void AboutBox::initStrings() { "Thiago Pimentel <thiago.merces@gmail.com>, 2006.\n" "Toshifumi Sato <sato@centrosystem.com>, 2005.\n" "Jon South <striker@lunar-linux.org>, 2006. \n" -"Uwe Schöler <oss@oss-marketplace.com>, 2006-2013.\n" +"Uwe Schöler <oss@oss-marketplace.com>, 2006-2014.\n" "Valek Filippov <frob@df.ru>, 2000, 2003.\n" "Victor Dachev <vdachev@gmail.com>, 2006.\n" +"Victor Westmann <victor.westmann@gmail.com>, 2011, 2014.\n" +"Ville Pätsi, 2013.\n" "Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu>, 2003.\n" "Vital Khilko <dojlid@mova.org>, 2003.\n" "Vitaly Lipatov <lav@altlinux.ru>, 2002, 2004.\n" @@ -584,7 +586,7 @@ void AboutBox::initStrings() { "Yaron Shahrabani <sh.yaron@gmail.com>, 2009.\n" "Yukihiro Nakai <nakai@gnome.gr.jp>, 2000, 2003.\n" "Yuri Beznos <zhiz0id@gmail.com>, 2006.\n" -"Yuri Chornoivan <yurchor@ukr.net>, 2007-2013.\n" +"Yuri Chornoivan <yurchor@ukr.net>, 2007-2014.\n" "Yuri Syrota <rasta@renome.rovno.ua>, 2000.\n" "Yves Guillou <yvesguillou@users.sourceforge.net>, 2004.\n" "Zdenko Podobný <zdpo@mailbox.sk>, 2003, 2004." diff --git a/src/ui/object-edit.cpp b/src/ui/object-edit.cpp index cc96727f8..ca550502d 100644 --- a/src/ui/object-edit.cpp +++ b/src/ui/object-edit.cpp @@ -6,6 +6,7 @@ * Mitsuru Oka * Maximilian Albert <maximilian.albert@gmail.com> * Abhishek Sharma + * Jon A. Cruz <jon@joncruz.org> * * Licensed under GNU GPL */ @@ -42,11 +43,11 @@ namespace { -static KnotHolder *sp_lpe_knot_holder(SPItem *item, SPDesktop *desktop) +static KnotHolder *sp_lpe_knot_holder(SPLPEItem *item, SPDesktop *desktop) { KnotHolder *knot_holder = new KnotHolder(desktop, item, NULL); - Inkscape::LivePathEffect::Effect *effect = SP_LPE_ITEM(item)->getCurrentLPE(); + Inkscape::LivePathEffect::Effect *effect = item->getCurrentLPE(); effect->addHandles(knot_holder, desktop, item); return knot_holder; @@ -61,29 +62,33 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) { KnotHolder *knotholder = NULL; - if (SP_IS_LPE_ITEM(item) && - SP_LPE_ITEM(item)->getCurrentLPE() && - SP_LPE_ITEM(item)->getCurrentLPE()->isVisible() && - SP_LPE_ITEM(item)->getCurrentLPE()->providesKnotholder()) { - knotholder = sp_lpe_knot_holder(item, desktop); - } else if (SP_IS_RECT(item)) { + SPLPEItem *lpe = dynamic_cast<SPLPEItem *>(item); + if (lpe && + lpe->getCurrentLPE() && + lpe->getCurrentLPE()->isVisible() && + lpe->getCurrentLPE()->providesKnotholder()) { + knotholder = sp_lpe_knot_holder(lpe, desktop); + } else if (dynamic_cast<SPRect *>(item)) { knotholder = new RectKnotHolder(desktop, item, NULL); - } else if (SP_IS_BOX3D(item)) { + } else if (dynamic_cast<SPBox3D *>(item)) { knotholder = new Box3DKnotHolder(desktop, item, NULL); - } else if (SP_IS_GENERICELLIPSE(item)) { + } else if (dynamic_cast<SPGenericEllipse *>(item)) { knotholder = new ArcKnotHolder(desktop, item, NULL); - } else if (SP_IS_STAR(item)) { + } else if (dynamic_cast<SPStar *>(item)) { knotholder = new StarKnotHolder(desktop, item, NULL); - } else if (SP_IS_SPIRAL(item)) { + } else if (dynamic_cast<SPSpiral *>(item)) { knotholder = new SpiralKnotHolder(desktop, item, NULL); - } else if (SP_IS_OFFSET(item)) { + } else if (dynamic_cast<SPOffset *>(item)) { knotholder = new OffsetKnotHolder(desktop, item, NULL); - } else if (SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { - knotholder = new FlowtextKnotHolder(desktop, SP_FLOWTEXT(item)->get_frame(NULL), NULL); - } else if ((item->style->fill.isPaintserver() && SP_IS_PATTERN(item->style->getFillPaintServer())) || - (item->style->stroke.isPaintserver() && SP_IS_PATTERN(item->style->getStrokePaintServer()))) { - knotholder = new KnotHolder(desktop, item, NULL); - knotholder->add_pattern_knotholder(); + } else { + SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(item); + if (flowtext && flowtext->has_internal_frame()) { + knotholder = new FlowtextKnotHolder(desktop, flowtext->get_frame(NULL), NULL); + } else if ((item->style->fill.isPaintserver() && dynamic_cast<SPPattern *>(item->style->getFillPaintServer())) || + (item->style->stroke.isPaintserver() && dynamic_cast<SPPattern *>(item->style->getStrokePaintServer()))) { + knotholder = new KnotHolder(desktop, item, NULL); + knotholder->add_pattern_knotholder(); + } } return knotholder; @@ -130,7 +135,8 @@ public: Geom::Point RectKnotHolderEntityRX::knot_get() const { - SPRect *rect = SP_RECT(item); + SPRect *rect = dynamic_cast<SPRect *>(item); + g_assert(rect != NULL); return Geom::Point(rect->x.computed + rect->width.computed - rect->rx.computed, rect->y.computed); } @@ -138,7 +144,8 @@ RectKnotHolderEntityRX::knot_get() const void RectKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { - SPRect *rect = SP_RECT(item); + SPRect *rect = dynamic_cast<SPRect *>(item); + g_assert(rect != NULL); //In general we cannot just snap this radius to an arbitrary point, as we have only a single //degree of freedom. For snapping to an arbitrary point we need two DOF. If we're going to snap @@ -157,13 +164,14 @@ RectKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*orig update_knot(); - (static_cast<SPObject*>(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + rect->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } void RectKnotHolderEntityRX::knot_click(unsigned int state) { - SPRect *rect = SP_RECT(item); + SPRect *rect = dynamic_cast<SPRect *>(item); + g_assert(rect != NULL); if (state & GDK_SHIFT_MASK) { /* remove rounding from rectangle */ @@ -179,7 +187,8 @@ RectKnotHolderEntityRX::knot_click(unsigned int state) Geom::Point RectKnotHolderEntityRY::knot_get() const { - SPRect *rect = SP_RECT(item); + SPRect *rect = dynamic_cast<SPRect *>(item); + g_assert(rect != NULL); return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->ry.computed); } @@ -187,7 +196,8 @@ RectKnotHolderEntityRY::knot_get() const void RectKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { - SPRect *rect = SP_RECT(item); + SPRect *rect = dynamic_cast<SPRect *>(item); + g_assert(rect != NULL); //In general we cannot just snap this radius to an arbitrary point, as we have only a single //degree of freedom. For snapping to an arbitrary point we need two DOF. If we're going to snap @@ -215,13 +225,14 @@ RectKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*orig update_knot(); - (static_cast<SPObject *>(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + rect->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } void RectKnotHolderEntityRY::knot_click(unsigned int state) { - SPRect *rect = SP_RECT(item); + SPRect *rect = dynamic_cast<SPRect *>(item); + g_assert(rect != NULL); if (state & GDK_SHIFT_MASK) { /* remove rounding */ @@ -251,7 +262,8 @@ static void sp_rect_clamp_radii(SPRect *rect) Geom::Point RectKnotHolderEntityWH::knot_get() const { - SPRect *rect = SP_RECT(item); + SPRect *rect = dynamic_cast<SPRect *>(item); + g_assert(rect != NULL); return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); } @@ -259,7 +271,8 @@ RectKnotHolderEntityWH::knot_get() const void RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &origin, unsigned int state) { - SPRect *rect = SP_RECT(item); + SPRect *rect = dynamic_cast<SPRect *>(item); + g_assert(rect != NULL); Geom::Point s = p; @@ -325,7 +338,7 @@ RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &or sp_rect_clamp_radii(rect); - (static_cast<SPObject *>(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + rect->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } void @@ -338,7 +351,8 @@ RectKnotHolderEntityWH::knot_set(Geom::Point const &p, Geom::Point const &origin Geom::Point RectKnotHolderEntityXY::knot_get() const { - SPRect *rect = SP_RECT(item); + SPRect *rect = dynamic_cast<SPRect *>(item); + g_assert(rect != NULL); return Geom::Point(rect->x.computed, rect->y.computed); } @@ -346,7 +360,8 @@ RectKnotHolderEntityXY::knot_get() const void RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) { - SPRect *rect = SP_RECT(item); + SPRect *rect = dynamic_cast<SPRect *>(item); + g_assert(rect != NULL); // opposite corner (unmoved) gdouble opposite_x = (rect->x.computed + rect->width.computed); @@ -426,7 +441,7 @@ RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin update_knot(); - (static_cast<SPObject *>(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + rect->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } RectKnotHolder::RectKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : @@ -479,7 +494,12 @@ public: Geom::Point Box3DKnotHolderEntity::knot_get_generic(SPItem *item, unsigned int knot_id) const { - return box3d_get_corner_screen(SP_BOX3D(item), knot_id); + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box) { + return box3d_get_corner_screen(box, knot_id); + } else { + return Geom::Point(); // TODO investigate proper fallback + } } void @@ -488,7 +508,8 @@ Box3DKnotHolderEntity::knot_set_generic(SPItem *item, unsigned int knot_id, Geom Geom::Point const s = snap_knot_position(new_pos, state); g_assert(item != NULL); - SPBox3D *box = SP_BOX3D(item); + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + g_assert(box != NULL); Geom::Affine const i2dt (item->i2dt_affine ()); Box3D::Axis movement; @@ -608,7 +629,12 @@ Box3DKnotHolderEntity7::knot_get() const Geom::Point Box3DKnotHolderEntityCenter::knot_get() const { - return box3d_get_center_screen(SP_BOX3D(item)); + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box) { + return box3d_get_center_screen(box); + } else { + return Geom::Point(); // TODO investigate proper fallback + } } void @@ -664,10 +690,11 @@ Box3DKnotHolderEntityCenter::knot_set(Geom::Point const &new_pos, Geom::Point co { Geom::Point const s = snap_knot_position(new_pos, state); - SPBox3D *box = SP_BOX3D(item); + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + g_assert(box != NULL); Geom::Affine const i2dt (item->i2dt_affine ()); - box3d_set_center (SP_BOX3D(item), s * i2dt, origin * i2dt, !(state & GDK_SHIFT_MASK) ? Box3D::XY : Box3D::Z, + box3d_set_center(box, s * i2dt, origin * i2dt, !(state & GDK_SHIFT_MASK) ? Box3D::XY : Box3D::Z, state & GDK_CONTROL_MASK); box3d_set_z_orders(box); @@ -789,7 +816,8 @@ ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*or { int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); - SPGenericEllipse *arc = SP_GENERICELLIPSE(item); + SPGenericEllipse *arc = dynamic_cast<SPGenericEllipse *>(item); + g_assert(arc != NULL); arc->setClosed(sp_genericellipse_side(arc, p) == -1); @@ -809,7 +837,8 @@ ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*or Geom::Point ArcKnotHolderEntityStart::knot_get() const { - SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + SPGenericEllipse const *ge = dynamic_cast<SPGenericEllipse const *>(item); + g_assert(ge != NULL); return ge->getPointAtAngle(ge->start); } @@ -817,11 +846,12 @@ ArcKnotHolderEntityStart::knot_get() const void ArcKnotHolderEntityStart::knot_click(unsigned int state) { - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPGenericEllipse *ge = dynamic_cast<SPGenericEllipse *>(item); + g_assert(ge != NULL); if (state & GDK_SHIFT_MASK) { ge->end = ge->start = 0; - (static_cast<SPObject *>(ge))->updateRepr(); + ge->updateRepr(); } } @@ -830,7 +860,8 @@ ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*orig { int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); - SPGenericEllipse *arc = SP_GENERICELLIPSE(item); + SPGenericEllipse *arc = dynamic_cast<SPGenericEllipse *>(item); + g_assert(arc != NULL); arc->setClosed(sp_genericellipse_side(arc, p) == -1); @@ -850,7 +881,8 @@ ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*orig Geom::Point ArcKnotHolderEntityEnd::knot_get() const { - SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + SPGenericEllipse const *ge = dynamic_cast<SPGenericEllipse const *>(item); + g_assert(ge != NULL); return ge->getPointAtAngle(ge->end); } @@ -859,11 +891,12 @@ ArcKnotHolderEntityEnd::knot_get() const void ArcKnotHolderEntityEnd::knot_click(unsigned int state) { - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPGenericEllipse *ge = dynamic_cast<SPGenericEllipse *>(item); + g_assert(ge != NULL); if (state & GDK_SHIFT_MASK) { ge->end = ge->start = 0; - (static_cast<SPObject *>(ge))->updateRepr(); + ge->updateRepr(); } } @@ -871,7 +904,8 @@ ArcKnotHolderEntityEnd::knot_click(unsigned int state) void ArcKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPGenericEllipse *ge = dynamic_cast<SPGenericEllipse *>(item); + g_assert(ge != NULL); Geom::Point const s = snap_knot_position(p, state); @@ -881,13 +915,14 @@ ArcKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origi ge->ry.computed = ge->rx.computed; } - (static_cast<SPObject *>(item))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } Geom::Point ArcKnotHolderEntityRX::knot_get() const { - SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + SPGenericEllipse const *ge = dynamic_cast<SPGenericEllipse const *>(item); + g_assert(ge != NULL); return (Geom::Point(ge->cx.computed, ge->cy.computed) - Geom::Point(ge->rx.computed, 0)); } @@ -895,18 +930,20 @@ ArcKnotHolderEntityRX::knot_get() const void ArcKnotHolderEntityRX::knot_click(unsigned int state) { - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPGenericEllipse *ge = dynamic_cast<SPGenericEllipse *>(item); + g_assert(ge != NULL); if (state & GDK_CONTROL_MASK) { ge->ry.computed = ge->rx.computed; - (static_cast<SPObject *>(ge))->updateRepr(); + ge->updateRepr(); } } void ArcKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPGenericEllipse *ge = dynamic_cast<SPGenericEllipse *>(item); + g_assert(ge != NULL); Geom::Point const s = snap_knot_position(p, state); @@ -916,13 +953,14 @@ ArcKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origi ge->rx.computed = ge->ry.computed; } - (static_cast<SPObject *>(item))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } Geom::Point ArcKnotHolderEntityRY::knot_get() const { - SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + SPGenericEllipse const *ge = dynamic_cast<SPGenericEllipse *>(item); + g_assert(ge != NULL); return (Geom::Point(ge->cx.computed, ge->cy.computed) - Geom::Point(0, ge->ry.computed)); } @@ -930,11 +968,12 @@ ArcKnotHolderEntityRY::knot_get() const void ArcKnotHolderEntityRY::knot_click(unsigned int state) { - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPGenericEllipse *ge = dynamic_cast<SPGenericEllipse *>(item); + g_assert(ge != NULL); if (state & GDK_CONTROL_MASK) { ge->rx.computed = ge->ry.computed; - (static_cast<SPObject *>(ge))->updateRepr(); + ge->updateRepr(); } } @@ -991,7 +1030,8 @@ public: void StarKnotHolderEntity1::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { - SPStar *star = SP_STAR(item); + SPStar *star = dynamic_cast<SPStar *>(item); + g_assert(star != NULL); Geom::Point const s = snap_knot_position(p, state); @@ -1011,13 +1051,14 @@ StarKnotHolderEntity1::knot_set(Geom::Point const &p, Geom::Point const &/*origi star->arg[0] = arg1; star->arg[1] += darg1; } - (static_cast<SPObject *>(star))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + star->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } void StarKnotHolderEntity2::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { - SPStar *star = SP_STAR(item); + SPStar *star = dynamic_cast<SPStar *>(item); + g_assert(star != NULL); Geom::Point const s = snap_knot_position(p, state); @@ -1039,7 +1080,7 @@ StarKnotHolderEntity2::knot_set(Geom::Point const &p, Geom::Point const &/*origi star->r[1] = L2(d); star->arg[1] = atan2(d); } - (static_cast<SPObject *>(star))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + star->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } @@ -1048,7 +1089,8 @@ StarKnotHolderEntity1::knot_get() const { g_assert(item != NULL); - SPStar const *star = SP_STAR(item); + SPStar const *star = dynamic_cast<SPStar const *>(item); + g_assert(star != NULL); return sp_star_get_xy(star, SP_STAR_POINT_KNOT1, 0); @@ -1059,7 +1101,8 @@ StarKnotHolderEntity2::knot_get() const { g_assert(item != NULL); - SPStar const *star = SP_STAR(item); + SPStar const *star = dynamic_cast<SPStar const *>(item); + g_assert(star != NULL); return sp_star_get_xy(star, SP_STAR_POINT_KNOT2, 0); } @@ -1067,17 +1110,18 @@ StarKnotHolderEntity2::knot_get() const static void sp_star_knot_click(SPItem *item, unsigned int state) { - SPStar *star = SP_STAR(item); + SPStar *star = dynamic_cast<SPStar *>(item); + g_assert(star != NULL); if (state & GDK_MOD1_MASK) { star->randomized = 0; - (static_cast<SPObject *>(star))->updateRepr(); + star->updateRepr(); } else if (state & GDK_SHIFT_MASK) { star->rounded = 0; - (static_cast<SPObject *>(star))->updateRepr(); + star->updateRepr(); } else if (state & GDK_CONTROL_MASK) { star->arg[1] = star->arg[0] + M_PI / star->sides; - (static_cast<SPObject *>(star))->updateRepr(); + star->updateRepr(); } } @@ -1096,7 +1140,8 @@ StarKnotHolderEntity2::knot_click(unsigned int state) StarKnotHolder::StarKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : KnotHolder(desktop, item, relhandler) { - SPStar *star = SP_STAR(item); + SPStar *star = dynamic_cast<SPStar *>(item); + g_assert(item != NULL); StarKnotHolderEntity1 *entity1 = new StarKnotHolderEntity1(); entity1->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, @@ -1144,7 +1189,8 @@ SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &o Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); - SPSpiral *spiral = SP_SPIRAL(item); + SPSpiral *spiral = dynamic_cast<SPSpiral *>(item); + g_assert(spiral != NULL); gdouble dx = p[Geom::X] - spiral->cx; gdouble dy = p[Geom::Y] - spiral->cy; @@ -1179,7 +1225,7 @@ SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &o spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999); } - (static_cast<SPObject *>(spiral))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + spiral->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } /* @@ -1193,7 +1239,8 @@ SpiralKnotHolderEntityOuter::knot_set(Geom::Point const &p, Geom::Point const &/ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); - SPSpiral *spiral = SP_SPIRAL(item); + SPSpiral *spiral = dynamic_cast<SPSpiral *>(item); + g_assert(spiral != NULL); gdouble dx = p[Geom::X] - spiral->cx; gdouble dy = p[Geom::Y] - spiral->cy; @@ -1258,13 +1305,14 @@ SpiralKnotHolderEntityOuter::knot_set(Geom::Point const &p, Geom::Point const &/ spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999); } - (static_cast<SPObject *>(spiral))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + spiral->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } Geom::Point SpiralKnotHolderEntityInner::knot_get() const { - SPSpiral const *spiral = SP_SPIRAL(item); + SPSpiral const *spiral = dynamic_cast<SPSpiral const *>(item); + g_assert(spiral != NULL); return spiral->getXY(spiral->t0); } @@ -1272,7 +1320,8 @@ SpiralKnotHolderEntityInner::knot_get() const Geom::Point SpiralKnotHolderEntityOuter::knot_get() const { - SPSpiral const *spiral = SP_SPIRAL(item); + SPSpiral const *spiral = dynamic_cast<SPSpiral const *>(item); + g_assert(spiral != NULL); return spiral->getXY(1.0); } @@ -1280,14 +1329,15 @@ SpiralKnotHolderEntityOuter::knot_get() const void SpiralKnotHolderEntityInner::knot_click(unsigned int state) { - SPSpiral *spiral = SP_SPIRAL(item); + SPSpiral *spiral = dynamic_cast<SPSpiral *>(item); + g_assert(spiral != NULL); if (state & GDK_MOD1_MASK) { spiral->exp = 1; - (static_cast<SPObject *>(spiral))->updateRepr(); + spiral->updateRepr(); } else if (state & GDK_SHIFT_MASK) { spiral->t0 = 0; - (static_cast<SPObject *>(spiral))->updateRepr(); + spiral->updateRepr(); } } @@ -1322,20 +1372,22 @@ public: void OffsetKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int /*state*/) { - SPOffset *offset = SP_OFFSET(item); + SPOffset *offset = dynamic_cast<SPOffset *>(item); + g_assert(offset != NULL); offset->rad = sp_offset_distance_to_original(offset, p); offset->knot = p; offset->knotSet = true; - (static_cast<SPObject *>(offset))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + offset->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } Geom::Point OffsetKnotHolderEntity::knot_get() const { - SPOffset const *offset = SP_OFFSET(item); + SPOffset const *offset = dynamic_cast<SPOffset const *>(item); + g_assert(offset != NULL); Geom::Point np; sp_offset_top_point(offset,&np); @@ -1365,7 +1417,8 @@ public: Geom::Point FlowtextKnotHolderEntity::knot_get() const { - SPRect const *rect = SP_RECT(item); + SPRect const *rect = dynamic_cast<SPRect const *>(item); + g_assert(rect != NULL); return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); } diff --git a/src/ui/tools-switch.cpp b/src/ui/tools-switch.cpp index 79d6b8930..07d68471f 100644 --- a/src/ui/tools-switch.cpp +++ b/src/ui/tools-switch.cpp @@ -4,6 +4,7 @@ * Authors: * bulia byak <buliabyak@users.sf.net> * Josh Andler <scislac@users.sf.net> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2003-2007 authors * @@ -59,6 +60,8 @@ #include "message-context.h" +using Inkscape::UI::Tools::ToolBase; + static char const *const tool_names[] = { NULL, "/tools/select", @@ -130,9 +133,11 @@ int tools_isactive(SPDesktop *dt, unsigned num) { g_assert( num < G_N_ELEMENTS(tool_names) ); - if (SP_IS_EVENT_CONTEXT(dt->event_context)) + if (dynamic_cast<ToolBase *>(dt->event_context)) { return dt->event_context->pref_observer->observed_path == tool_names[num]; - else return FALSE; + } else { + return FALSE; + } } int @@ -159,27 +164,27 @@ tools_switch(SPDesktop *dt, int num) void tools_switch_by_item(SPDesktop *dt, SPItem *item, Geom::Point const p) { - if (SP_IS_RECT(item)) { + if (dynamic_cast<SPRect *>(item)) { tools_switch(dt, TOOLS_SHAPES_RECT); - } else if (SP_IS_BOX3D(item)) { + } else if (dynamic_cast<SPBox3D *>(item)) { tools_switch(dt, TOOLS_SHAPES_3DBOX); - } else if (SP_IS_GENERICELLIPSE(item)) { + } else if (dynamic_cast<SPGenericEllipse *>(item)) { tools_switch(dt, TOOLS_SHAPES_ARC); - } else if (SP_IS_STAR(item)) { + } else if (dynamic_cast<SPStar *>(item)) { tools_switch(dt, TOOLS_SHAPES_STAR); - } else if (SP_IS_SPIRAL(item)) { + } else if (dynamic_cast<SPSpiral *>(item)) { tools_switch(dt, TOOLS_SHAPES_SPIRAL); - } else if (SP_IS_PATH(item)) { + } else if (dynamic_cast<SPPath *>(item)) { if (Inkscape::UI::Tools::cc_item_is_connector(item)) { tools_switch(dt, TOOLS_CONNECTOR); } else { tools_switch(dt, TOOLS_NODES); } - } else if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + } else if (dynamic_cast<SPText *>(item) || dynamic_cast<SPFlowtext *>(item)) { tools_switch(dt, TOOLS_TEXT); - sp_text_context_place_cursor_at (SP_TEXT_CONTEXT(dt->event_context), SP_OBJECT(item), p); - } else if (SP_IS_OFFSET(item)) { + sp_text_context_place_cursor_at (SP_TEXT_CONTEXT(dt->event_context), item, p); + } else if (dynamic_cast<SPOffset *>(item)) { tools_switch(dt, TOOLS_NODES); } } diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index 394b0b369..21459e5d0 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -264,15 +264,16 @@ sp_select_context_up_one_layer(SPDesktop *desktop) SPObject *const current_layer = desktop->currentLayer(); if (current_layer) { SPObject *const parent = current_layer->parent; + SPGroup *current_group = dynamic_cast<SPGroup *>(current_layer); if ( parent && ( parent->parent - || !( SP_IS_GROUP(current_layer) - && ( SPGroup::LAYER - == SP_GROUP(current_layer)->layerMode() ) ) ) ) + || !( current_group + && ( SPGroup::LAYER == current_group->layerMode() ) ) ) ) { desktop->setCurrentLayer(parent); - if (SP_IS_GROUP(current_layer) && SPGroup::LAYER != SP_GROUP(current_layer)->layerMode()) + if (current_group && (SPGroup::LAYER != current_group->layerMode())) { sp_desktop_selection(desktop)->set(current_layer); + } } } } @@ -403,7 +404,8 @@ void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *sele } Inkscape::DrawingItem *arenaitem; - SPItem *item = SP_ITEM(this->cycling_cur_item->data); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(cycling_cur_item->data)); + g_assert(item != NULL); // Deactivate current item if (!g_list_find(this->cycling_items_selected_before, item) && selection->includes(item)) { @@ -427,7 +429,8 @@ void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *sele if (next) { this->cycling_cur_item = next; - item = SP_ITEM(this->cycling_cur_item->data); + item = dynamic_cast<SPItem *>(static_cast<SPObject *>(this->cycling_cur_item->data)); + g_assert(item != NULL); } arenaitem = item->get_arenaitem(desktop->dkey); @@ -442,8 +445,13 @@ void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *sele void SelectTool::sp_select_context_reset_opacities() { for (GList *l = this->cycling_items; l != NULL; l = g_list_next(l)) { - Inkscape::DrawingItem *arenaitem = SP_ITEM(l->data)->get_arenaitem(this->desktop->dkey); - arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(SP_ITEM(l->data)->style->opacity.value)); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(l->data)); + if (item) { + Inkscape::DrawingItem *arenaitem = item->get_arenaitem(desktop->dkey); + arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(item->style->opacity.value)); + } else { + g_assert_not_reached(); + } } g_list_free(this->cycling_items); @@ -475,8 +483,8 @@ bool SelectTool::root_handler(GdkEvent* event) { if (!selection->isEmpty()) { SPItem *clicked_item = static_cast<SPItem *>(selection->itemList()->data); - if (SP_IS_GROUP(clicked_item) && !SP_IS_BOX3D(clicked_item)) { // enter group if it's not a 3D box - desktop->setCurrentLayer(reinterpret_cast<SPObject *>(clicked_item)); + if (dynamic_cast<SPGroup *>(clicked_item) && !dynamic_cast<SPBox3D *>(clicked_item)) { // enter group if it's not a 3D box + desktop->setCurrentLayer(clicked_item); sp_desktop_selection(desktop)->clear(); this->dragging = false; sp_event_context_discard_delayed_snap_event(this); @@ -591,8 +599,11 @@ bool SelectTool::root_handler(GdkEvent* event) { item_in_group = desktop->getItemAtPoint(Geom::Point(event->button.x, event->button.y), TRUE); group_at_point = desktop->getGroupAtPoint(Geom::Point(event->button.x, event->button.y)); - if (SP_IS_LAYER(selection->single())) { - group_at_point = SP_GROUP(selection->single()); + { + SPGroup *selGroup = dynamic_cast<SPGroup *>(selection->single()); + if (selGroup && (selGroup->layerMode() == SPGroup::LAYER)) { + group_at_point = selGroup; + } } // group-at-point is meant to be topmost item if it's a group, @@ -673,10 +684,11 @@ bool SelectTool::root_handler(GdkEvent* event) { selection->toggle(this->item); } else { SPObject* single = selection->single(); + SPGroup *singleGroup = dynamic_cast<SPGroup *>(single); // without shift, increase state (i.e. toggle scale/rotation handles) if (selection->includes(this->item)) { _seltrans->increaseState(); - } else if (SP_IS_LAYER(single) && single->isAncestorOf(this->item)) { + } else if (singleGroup && (singleGroup->layerMode() == SPGroup::LAYER) && single->isAncestorOf(this->item)) { _seltrans->increaseState(); } else { _seltrans->resetState(); @@ -818,7 +830,7 @@ bool SelectTool::root_handler(GdkEvent* event) { SPItem *item = desktop->getItemAtPoint(p, true, NULL); // Save pointer to current cycle-item so that we can find it again later, in the freshly built list - SPItem *tmp_cur_item = this->cycling_cur_item ? SP_ITEM(this->cycling_cur_item->data) : NULL; + SPItem *tmp_cur_item = this->cycling_cur_item ? dynamic_cast<SPItem *>(static_cast<SPObject *>(this->cycling_cur_item->data)) : NULL; g_list_free(this->cycling_items); this->cycling_items = NULL; this->cycling_cur_item = NULL; @@ -851,11 +863,14 @@ bool SelectTool::root_handler(GdkEvent* event) { Inkscape::DrawingItem *arenaitem; for(GList *l = this->cycling_items_cmp; l != NULL; l = l->next) { - arenaitem = SP_ITEM(l->data)->get_arenaitem(desktop->dkey); - arenaitem->setOpacity(1.0); - //if (!shift_pressed && !g_list_find(this->cycling_items_selected_before, SP_ITEM(l->data)) && selection->includes(SP_ITEM(l->data))) - if (!g_list_find(this->cycling_items_selected_before, SP_ITEM(l->data)) && selection->includes(SP_ITEM(l->data))) { - selection->remove(SP_ITEM(l->data)); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(l->data)); + if (item) { + arenaitem = item->get_arenaitem(desktop->dkey); + arenaitem->setOpacity(1.0); + //if (!shift_pressed && !g_list_find(this->cycling_items_selected_before, item) && selection->includes(item)) + if (!g_list_find(this->cycling_items_selected_before, item) && selection->includes(item)) { + selection->remove(item); + } } } @@ -869,16 +884,19 @@ bool SelectTool::root_handler(GdkEvent* event) { // ... and rebuild them with the new items. this->cycling_items_cmp = g_list_copy(this->cycling_items); - SPItem *item; for(GList *l = this->cycling_items; l != NULL; l = l->next) { - item = SP_ITEM(l->data); - arenaitem = item->get_arenaitem(desktop->dkey); - arenaitem->setOpacity(0.3); - - if (selection->includes(item)) { - // already selected items are stored separately, too - this->cycling_items_selected_before = g_list_append(this->cycling_items_selected_before, item); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(l->data)); + if (item) { + arenaitem = item->get_arenaitem(desktop->dkey); + arenaitem->setOpacity(0.3); + + if (selection->includes(item)) { + // already selected items are stored separately, too + this->cycling_items_selected_before = g_list_append(this->cycling_items_selected_before, item); + } + } else { + g_assert_not_reached(); } } @@ -1134,9 +1152,9 @@ bool SelectTool::root_handler(GdkEvent* event) { if (MOD__CTRL_ONLY(event)) { if (selection->singleItem()) { SPItem *clicked_item = selection->singleItem(); - - if ( SP_IS_GROUP(clicked_item) || SP_IS_BOX3D(clicked_item)) { // enter group or a 3D box - desktop->setCurrentLayer(reinterpret_cast<SPObject *>(clicked_item)); + SPGroup *clickedGroup = dynamic_cast<SPGroup *>(clicked_item); + if ( (clickedGroup && (clickedGroup->layerMode() == SPGroup::LAYER)) || dynamic_cast<SPBox3D *>(clicked_item)) { // enter group or a 3D box + desktop->setCurrentLayer(clicked_item); sp_desktop_selection(desktop)->clear(); } else { this->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Selected object is not a group. Cannot enter.")); diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 933da6fb1..cdc608558 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -384,11 +384,14 @@ static bool sp_spray_recursive(SPDesktop *desktop, gint _distrib) { bool did = false; - - if (SP_IS_BOX3D(item) ) { - // convert 3D boxes to ordinary groups before spraying their shapes - item = box3d_convert_to_group(SP_BOX3D(item)); - selection->add(item); + + { + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box) { + // convert 3D boxes to ordinary groups before spraying their shapes + item = box3d_convert_to_group(box); + selection->add(item); + } } double _fid = g_random_double_range(0, 1); @@ -413,7 +416,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, parent->appendChild(copy); SPObject *new_obj = doc->getObjectByRepr(copy); - item_copied = SP_ITEM(new_obj); // Convertion object->item + item_copied = dynamic_cast<SPItem *>(new_obj); // Convertion object->item Geom::Point center=item->getCenter(); sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale,_scale)); sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale)); @@ -437,7 +440,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, items != NULL; items = items->next) { - SPItem *item1 = SP_ITEM(items->data); + SPItem *item1 = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data)); if (i == 1) { parent_item = item1; } @@ -458,7 +461,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); parent->appendChild(copy); SPObject *new_obj = doc->getObjectByRepr(copy); - item_copied = SP_ITEM(new_obj); + item_copied = dynamic_cast<SPItem *>(new_obj); // Move around the cursor Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint()); @@ -503,7 +506,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, SPObject *clone_object = doc->getObjectByRepr(clone); // Conversion object->item - item_copied = SP_ITEM(clone_object); + item_copied = dynamic_cast<SPItem *>(clone_object); Geom::Point center = item->getCenter(); sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale)); sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale)); @@ -554,13 +557,16 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for (GSList *items = original_selection; items != NULL; items = items->next) { - sp_object_ref(SP_ITEM(items->data)); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data)); + g_assert(item != NULL); + sp_object_ref(item); } for (GSList *items = original_selection; items != NULL; items = items->next) { - SPItem *item = SP_ITEM(items->data); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data)); + g_assert(item != NULL); if (is_transform_modes(tc->mode)) { if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, move_force, tc->population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) { @@ -576,7 +582,9 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for (GSList *items = original_selection; items != NULL; items = items->next) { - sp_object_unref(SP_ITEM(items->data)); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data)); + g_assert(item != NULL); + sp_object_unref(item); } } diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index 340f64a0b..f56975de2 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -372,13 +372,16 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P { bool did = false; - if (SP_IS_BOX3D(item) && !is_transform_mode(mode) && !is_color_mode(mode)) { - // convert 3D boxes to ordinary groups before tweaking their shapes - item = box3d_convert_to_group(SP_BOX3D(item)); - selection->add(item); + { + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box && !is_transform_mode(mode) && !is_color_mode(mode)) { + // convert 3D boxes to ordinary groups before tweaking their shapes + item = box3d_convert_to_group(box); + selection->add(item); + } } - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + if (dynamic_cast<SPText *>(item) || dynamic_cast<SPFlowtext *>(item)) { GSList *items = g_slist_prepend (NULL, item); GSList *selected = NULL; GSList *to_select = NULL; @@ -387,22 +390,25 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P g_slist_free (items); SPObject* newObj = doc->getObjectByRepr(static_cast<Inkscape::XML::Node *>(to_select->data)); g_slist_free (to_select); - item = SP_ITEM(newObj); + item = dynamic_cast<SPItem *>(newObj); + g_assert(item != NULL); selection->add(item); } - if (SP_IS_GROUP(item) && !SP_IS_BOX3D(item)) { + if (dynamic_cast<SPGroup *>(item) && !dynamic_cast<SPBox3D *>(item)) { GSList *children = NULL; for (SPObject *child = item->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { + if (dynamic_cast<SPItem *>(static_cast<SPObject *>(child))) { children = g_slist_prepend(children, child); } } for (GSList *i = children; i; i = i->next) { - SPItem *child = SP_ITEM(i->data); - if (sp_tweak_dilate_recursive (selection, SP_ITEM(child), p, vector, mode, radius, force, fidelity, reverse)) + SPItem *child = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); + g_assert(child != NULL); + if (sp_tweak_dilate_recursive (selection, child, p, vector, mode, radius, force, fidelity, reverse)) { did = true; + } } g_slist_free(children); @@ -509,13 +515,13 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P } } - } else if (SP_IS_PATH(item) || SP_IS_SHAPE(item)) { + } else if (dynamic_cast<SPPath *>(item) || dynamic_cast<SPShape *>(item)) { Inkscape::XML::Node *newrepr = NULL; gint pos = 0; Inkscape::XML::Node *parent = NULL; char const *id = NULL; - if (!SP_IS_PATH(item)) { + if (!dynamic_cast<SPPath *>(item)) { newrepr = sp_selected_item_to_curved_repr(item, 0); if (!newrepr) { return false; @@ -631,7 +637,8 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P if (newrepr) { newrepr->setAttribute("d", str); } else { - if (SP_IS_LPE_ITEM(item) && SP_LPE_ITEM(item)->hasPathEffectRecursive()) { + SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); + if (lpeitem && lpeitem->hasPathEffectRecursive()) { item->getRepr()->setAttribute("inkscape:original-d", str); } else { item->getRepr()->setAttribute("d", str); @@ -769,7 +776,7 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or { SPGradient *gradient = getGradient(item, fill_or_stroke); - if (!gradient || !SP_IS_GRADIENT(gradient)) { + if (!gradient || !dynamic_cast<SPGradient *>(gradient)) { return; } @@ -780,9 +787,9 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or double pos = 0; double r = 0; - if (SP_IS_LINEARGRADIENT(gradient)) { - SPLinearGradient *lg = SP_LINEARGRADIENT(gradient); + SPLinearGradient *lg = dynamic_cast<SPLinearGradient *>(gradient); + if (lg) { Geom::Point p1(lg->x1.computed, lg->y1.computed); Geom::Point p2(lg->x2.computed, lg->y2.computed); Geom::Point pdiff(p2 - p1); @@ -800,11 +807,13 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or // Calculate radius in lenfth-of-gradient-line units r = radius / vl; - } else if (SP_IS_RADIALGRADIENT(gradient)) { - SPRadialGradient *rg = SP_RADIALGRADIENT(gradient); - Geom::Point c (rg->cx.computed, rg->cy.computed); - pos = Geom::L2(p - c) / rg->r.computed; - r = radius / rg->r.computed; + } else { + SPRadialGradient *rg = dynamic_cast<SPRadialGradient *>(gradient); + if (rg) { + Geom::Point c (rg->cx.computed, rg->cy.computed); + pos = Geom::L2(p - c) / rg->r.computed; + r = radius / rg->r.computed; + } } // Normalize pos to 0..1, taking into accound gradient spread: @@ -836,14 +845,16 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or double offset_h = 0; SPObject *child_prev = NULL; for (SPObject *child = vector->firstChild(); child; child = child->getNext()) { - if (!SP_IS_STOP(child)) { + SPStop *stop = dynamic_cast<SPStop *>(child); + if (!stop) { continue; } - SPStop *stop = SP_STOP (child); offset_h = stop->offset; if (child_prev) { + SPStop *prevStop = dynamic_cast<SPStop *>(child_prev); + g_assert(prevStop != NULL); if (offset_h - offset_l > r && pos_e >= offset_l && pos_e <= offset_h) { // the summit falls in this interstop, and the radius is small, @@ -853,9 +864,9 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or tweak_color (mode, stop->specified_color.v.c, rgb_goal, force * (pos_e - offset_l) / (offset_h - offset_l), do_h, do_s, do_l); - tweak_color (mode, SP_STOP(child_prev)->specified_color.v.c, rgb_goal, - force * (offset_h - pos_e) / (offset_h - offset_l), - do_h, do_s, do_l); + tweak_color(mode, prevStop->specified_color.v.c, rgb_goal, + force * (offset_h - pos_e) / (offset_h - offset_l), + do_h, do_s, do_l); stop->updateRepr(); child_prev->updateRepr(); break; @@ -863,9 +874,9 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or // wide brush, may affect more than 2 stops, // paint each stop by the force from the profile curve if (offset_l <= pos_e && offset_l > pos_e - r) { - tweak_color (mode, SP_STOP(child_prev)->specified_color.v.c, rgb_goal, - force * tweak_profile (fabs (pos_e - offset_l), r), - do_h, do_s, do_l); + tweak_color(mode, prevStop->specified_color.v.c, rgb_goal, + force * tweak_profile (fabs (pos_e - offset_l), r), + do_h, do_s, do_l); child_prev->updateRepr(); } @@ -894,10 +905,11 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, { bool did = false; - if (SP_IS_GROUP(item)) { + if (dynamic_cast<SPGroup *>(item)) { for (SPObject *child = item->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - if (sp_tweak_color_recursive (mode, SP_ITEM(child), item_at_point, + SPItem *childItem = dynamic_cast<SPItem *>(child); + if (childItem) { + if (sp_tweak_color_recursive (mode, childItem, item_at_point, fill_goal, do_fill, stroke_goal, do_stroke, opacity_goal, do_opacity, @@ -953,11 +965,11 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, //cycle through filter primitives SPObject *primitive_obj = style->getFilter()->children; while (primitive_obj) { - if (SP_IS_FILTER_PRIMITIVE(primitive_obj)) { - SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj); + SPFilterPrimitive *primitive = dynamic_cast<SPFilterPrimitive *>(primitive_obj); + if (primitive) { //if primitive is gaussianblur - if(SP_IS_GAUSSIANBLUR(primitive)) { - SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive); + SPGaussianBlur * spblur = dynamic_cast<SPGaussianBlur *>(primitive); + if (spblur) { float num = spblur->stdDeviation.getNumber(); blur_now += num * i2dt.descrim(); // sum all blurs in the filter } @@ -1080,7 +1092,7 @@ sp_tweak_dilate (TweakTool *tc, Geom::Point event_p, Geom::Point p, Geom::Point items != NULL; items = items->next) { - SPItem *item = SP_ITEM(items->data); + SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data)); if (is_color_mode (tc->mode)) { if (do_fill || do_stroke || do_opacity) { diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index f09e0d956..de42007aa 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -6,6 +6,7 @@ * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> * Maximilian Albert <Anhalter42@gmx.de> * Abhishek Sharma + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2005-2007 authors * @@ -256,11 +257,10 @@ std::list<SPBox3D *> VanishingPoint::selectedBoxes(Inkscape::Selection *sel) { std::list<SPBox3D *> sel_boxes; for (GSList const* i = sel->itemList(); i != NULL; i = i->next) { - if (!SP_IS_BOX3D(i->data)) - continue; - SPBox3D *box = SP_BOX3D(i->data); - if (this->hasBox(box)) { - sel_boxes.push_back (box); + SPItem *item = static_cast<SPItem *>(i->data); + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box && this->hasBox(box)) { + sel_boxes.push_back(box); } } return sel_boxes; @@ -396,12 +396,13 @@ VPDragger::VPsOfSelectedBoxes() { // FIXME: Should we take the selection from the parent VPDrag? I guess it shouldn't make a difference. Inkscape::Selection *sel = sp_desktop_selection(INKSCAPE.active_desktop()); for (GSList const* i = sel->itemList(); i != NULL; i = i->next) { - if (!SP_IS_BOX3D(i->data)) - continue; - SPBox3D *box = SP_BOX3D(i->data); - vp = this->findVPWithBox(box); - if (vp) { - sel_vps.insert (vp); + SPItem *item = static_cast<SPItem *>(i->data); + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box) { + vp = this->findVPWithBox(box); + if (vp) { + sel_vps.insert (vp); + } } } return sel_vps; @@ -577,14 +578,14 @@ VPDrag::updateDraggers () g_return_if_fail (this->selection != NULL); for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) { - SPItem *item = SP_ITEM(i->data); - if (!SP_IS_BOX3D (item)) continue; - SPBox3D *box = SP_BOX3D (item); - - VanishingPoint vp; - for (int i = 0; i < 3; ++i) { - vp.set(box3d_get_perspective(box), Proj::axes[i]); - addDragger (vp); + SPItem *item = static_cast<SPItem *>(i->data); + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box) { + VanishingPoint vp; + for (int i = 0; i < 3; ++i) { + vp.set(box3d_get_perspective(box), Proj::axes[i]); + addDragger (vp); + } } } } @@ -609,12 +610,13 @@ VPDrag::updateLines () g_return_if_fail (this->selection != NULL); for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) { - if (!SP_IS_BOX3D(i->data)) continue; - SPBox3D *box = SP_BOX3D (i->data); - - this->drawLinesForFace (box, Proj::X); - this->drawLinesForFace (box, Proj::Y); - this->drawLinesForFace (box, Proj::Z); + SPItem *item = static_cast<SPItem *>(i->data); + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box) { + this->drawLinesForFace (box, Proj::X); + this->drawLinesForFace (box, Proj::Y); + this->drawLinesForFace (box, Proj::Z); + } } } diff --git a/src/widgets/box3d-toolbar.cpp b/src/widgets/box3d-toolbar.cpp index f6e303d58..e0fa591f4 100644 --- a/src/widgets/box3d-toolbar.cpp +++ b/src/widgets/box3d-toolbar.cpp @@ -183,9 +183,9 @@ static void box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObj purge_repr_listener(tbl, tbl); SPItem *item = selection->singleItem(); - if (item && SP_IS_BOX3D(item)) { + SPBox3D *box = dynamic_cast<SPBox3D *>(item); + if (box) { // FIXME: Also deal with multiple selected boxes - SPBox3D *box = SP_BOX3D(item); Persp3D *persp = box3d_get_perspective(box); persp_repr = persp->getRepr(); if (persp_repr) { diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index cb18207f4..02dd5df6e 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -764,7 +764,7 @@ StrokeStyle::setJoinType (unsigned const jointype) break; default: // Should not happen - std::cerr << "StrokeStyle::setJoinType(): Invalid value" << std::endl; + std::cerr << "StrokeStyle::setJoinType(): Invalid value: " << jointype << std::endl; tb = joinMiter; break; } @@ -790,7 +790,7 @@ StrokeStyle::setCapType (unsigned const captype) break; default: // Should not happen - std::cerr << "StrokeStyle::setCapType(): Invalid value" << std::endl; + std::cerr << "StrokeStyle::setCapType(): Invalid value: " << captype << std::endl; tb = capButt; break; } @@ -884,13 +884,15 @@ StrokeStyle::updateLine() miterLimitAdj->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? #endif - if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT) { + if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT && + result_join != QUERY_STYLE_NOTHING ) { setJoinType(query->stroke_linejoin.value); } else { setJoinButtons(NULL); } - if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT) { + if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT && + result_cap != QUERY_STYLE_NOTHING ) { setCapType (query->stroke_linecap.value); } else { setCapButtons(NULL); |
