diff options
| -rw-r--r-- | src/ui/shape-editor-knotholders.cpp | 231 |
1 files changed, 130 insertions, 101 deletions
diff --git a/src/ui/shape-editor-knotholders.cpp b/src/ui/shape-editor-knotholders.cpp index 3e90f796c..67c109f58 100644 --- a/src/ui/shape-editor-knotholders.cpp +++ b/src/ui/shape-editor-knotholders.cpp @@ -1652,87 +1652,70 @@ TextKnotHolderEntityInlineSize::knot_get() const SPText *text = dynamic_cast<SPText *>(item); g_assert(text != nullptr); - Geom::Point p; + SPStyle* style = text->style; + double inline_size = style->inline_size.computed; + unsigned mode = style->writing_mode.computed; + unsigned anchor = style->text_anchor.computed; + unsigned direction = style->direction.computed; - if (text->style->shape_inside.set) { - // SVG 2 'shape-inside'. We only get here if there is a rectangle shape. + Geom::Point p(text->attributes.firstXY()); + + if (text->style->inline_size.set) { + // SVG 2 'inline-size' - Geom::OptRect frame = text->get_frame(); - if (frame) { - p = (*frame).corner(2); + // Keep handle at end of text line. + if (mode == SP_CSS_WRITING_MODE_LR_TB || + mode == SP_CSS_WRITING_MODE_RL_TB) { + // horizontal + if ( (direction == SP_CSS_DIRECTION_LTR && anchor == SP_CSS_TEXT_ANCHOR_START ) || + (direction == SP_CSS_DIRECTION_RTL && anchor == SP_CSS_TEXT_ANCHOR_END) ) { + p *= Geom::Translate (inline_size, 0); + } else if ( direction == SP_CSS_DIRECTION_LTR && anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { + p *= Geom::Translate (inline_size/2.0, 0 ); + } else if ( direction == SP_CSS_DIRECTION_RTL && anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { + p *= Geom::Translate (-inline_size/2.0, 0 ); + } else if ( (direction == SP_CSS_DIRECTION_LTR && anchor == SP_CSS_TEXT_ANCHOR_END ) || + (direction == SP_CSS_DIRECTION_RTL && anchor == SP_CSS_TEXT_ANCHOR_START) ) { + p *= Geom::Translate (-inline_size, 0); + } } else { - std::cerr << "TextKnotHolderEntityInlineSize::knot_get(): no frame!" << std::endl; + // vertical + if (anchor == SP_CSS_TEXT_ANCHOR_START) { + p *= Geom::Translate (0, inline_size); + } else if (anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { + p *= Geom::Translate (0, inline_size/2.0); + } else if (anchor == SP_CSS_TEXT_ANCHOR_END) { + p *= Geom::Translate (0, -inline_size); + } } - } else { - // 'shape-inside' or normal text. - - SPStyle* style = text->style; - - double inline_size = style->inline_size.computed; - unsigned mode = style->writing_mode.computed; - unsigned anchor = style->text_anchor.computed; - unsigned direction = style->direction.computed; - - p = text->attributes.firstXY(); - - if (text->style->inline_size.set) { - // SVG 2 'inline-size' - - // Keep handle at end of text line. + // Normal single line text. + Geom::OptRect bbox = text->geometricBounds(); // Check if this is best. + if (bbox) { if (mode == SP_CSS_WRITING_MODE_LR_TB || mode == SP_CSS_WRITING_MODE_RL_TB) { // horizontal if ( (direction == SP_CSS_DIRECTION_LTR && anchor == SP_CSS_TEXT_ANCHOR_START ) || (direction == SP_CSS_DIRECTION_RTL && anchor == SP_CSS_TEXT_ANCHOR_END) ) { - p *= Geom::Translate (inline_size, 0); + p *= Geom::Translate ((*bbox).width(), 0); } else if ( direction == SP_CSS_DIRECTION_LTR && anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { - p *= Geom::Translate (inline_size/2.0, 0 ); + p *= Geom::Translate ((*bbox).width()/2, 0); } else if ( direction == SP_CSS_DIRECTION_RTL && anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { - p *= Geom::Translate (-inline_size/2.0, 0 ); + p *= Geom::Translate (-(*bbox).width()/2, 0); } else if ( (direction == SP_CSS_DIRECTION_LTR && anchor == SP_CSS_TEXT_ANCHOR_END ) || (direction == SP_CSS_DIRECTION_RTL && anchor == SP_CSS_TEXT_ANCHOR_START) ) { - p *= Geom::Translate (-inline_size, 0); + p *= Geom::Translate (-(*bbox).width(), 0); } } else { // vertical if (anchor == SP_CSS_TEXT_ANCHOR_START) { - p *= Geom::Translate (0, inline_size); + p *= Geom::Translate (0, (*bbox).height()); } else if (anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { - p *= Geom::Translate (0, inline_size/2.0); + p *= Geom::Translate (0, (*bbox).height()/2); } else if (anchor == SP_CSS_TEXT_ANCHOR_END) { - p *= Geom::Translate (0, -inline_size); - } - } - } else { - // Normal single line text. - Geom::OptRect bbox = text->geometricBounds(); // Check if this is best. - if (bbox) { - if (mode == SP_CSS_WRITING_MODE_LR_TB || - mode == SP_CSS_WRITING_MODE_RL_TB) { - // horizontal - if ( (direction == SP_CSS_DIRECTION_LTR && anchor == SP_CSS_TEXT_ANCHOR_START ) || - (direction == SP_CSS_DIRECTION_RTL && anchor == SP_CSS_TEXT_ANCHOR_END) ) { - p *= Geom::Translate ((*bbox).width(), 0); - } else if ( direction == SP_CSS_DIRECTION_LTR && anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { - p *= Geom::Translate ((*bbox).width()/2, 0); - } else if ( direction == SP_CSS_DIRECTION_RTL && anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { - p *= Geom::Translate (-(*bbox).width()/2, 0); - } else if ( (direction == SP_CSS_DIRECTION_LTR && anchor == SP_CSS_TEXT_ANCHOR_END ) || - (direction == SP_CSS_DIRECTION_RTL && anchor == SP_CSS_TEXT_ANCHOR_START) ) { - p *= Geom::Translate (-(*bbox).width(), 0); - } - } else { - // vertical - if (anchor == SP_CSS_TEXT_ANCHOR_START) { - p *= Geom::Translate (0, (*bbox).height()); - } else if (anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { - p *= Geom::Translate (0, (*bbox).height()/2); - } else if (anchor == SP_CSS_TEXT_ANCHOR_END) { - p *= Geom::Translate (0, -(*bbox).height()); - } - p += Geom::Point((*bbox).width(), 0); // Keep on right side + p *= Geom::Translate (0, -(*bbox).height()); } + p += Geom::Point((*bbox).width(), 0); // Keep on right side } } } @@ -1746,45 +1729,26 @@ TextKnotHolderEntityInlineSize::knot_set(Geom::Point const &p, Geom::Point const SPText *text = dynamic_cast<SPText *>(item); g_assert(text != nullptr); - Geom::Point const s = snap_knot_position(p, state); - - if (text->style->shape_inside.set) { - // Text in a shape: rectangle - - Inkscape::XML::Node* rectangle = text->get_first_rectangle(); - double x = 0.0; - double y = 0.0; - sp_repr_get_double (rectangle, "x", &x); - sp_repr_get_double (rectangle, "y", &y); - double width = s[Geom::X] - x; - double height = s[Geom::Y] - y; - sp_repr_set_svg_double (rectangle, "width", width); - sp_repr_set_svg_double (rectangle, "height", height); + SPStyle* style = text->style; + unsigned mode = style->writing_mode.computed; + unsigned anchor = style->text_anchor.computed; + unsigned direction = style->direction.computed; + Geom::Point const s = snap_knot_position(p, state); + Geom::Point delta = s - text->attributes.firstXY(); + double size = 0.0; + if (mode == SP_CSS_WRITING_MODE_LR_TB || + mode == SP_CSS_WRITING_MODE_RL_TB) { + size = abs(delta[Geom::X]); } else { - // Normal or 'inline-size' text. - - SPStyle* style = text->style; - - unsigned mode = style->writing_mode.computed; - unsigned anchor = style->text_anchor.computed; - unsigned direction = style->direction.computed; - - Geom::Point delta = s - text->attributes.firstXY(); - double size = 0.0; - if (mode == SP_CSS_WRITING_MODE_LR_TB || - mode == SP_CSS_WRITING_MODE_RL_TB) { - size = abs(delta[Geom::X]); - } else { - size = delta[Geom::Y]; - } - if (anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { - size *= 2.0; - } - - text->style->inline_size.setDouble(abs(size)); - text->style->inline_size.set = true; + size = delta[Geom::Y]; } + if (anchor == SP_CSS_TEXT_ANCHOR_MIDDLE) { + size *= 2.0; + } + + text->style->inline_size.setDouble(abs(size)); + text->style->inline_size.set = true; text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); text->updateRepr(); @@ -1804,16 +1768,81 @@ TextKnotHolderEntityInlineSize::knot_click(unsigned int state) text->updateRepr(); } +class TextKnotHolderEntityShapeInside : public KnotHolderEntity { +public: + Geom::Point knot_get() const override; + void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) override; +}; + +Geom::Point +TextKnotHolderEntityShapeInside::knot_get() const +{ + // SVG 2 'shape-inside'. We only get here if there is a rectangle shape. + SPText *text = dynamic_cast<SPText *>(item); + g_assert(text != nullptr); + g_assert(text->style->shape_inside.set); + + Geom::Point p; + Geom::OptRect frame = text->get_frame(); + if (frame) { + p = (*frame).corner(2); + } else { + std::cerr << "TextKnotHolderEntityShapeInside::knot_get(): no frame!" << std::endl; + } + + return p; +} + +void +TextKnotHolderEntityShapeInside::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + // Text in a shape: rectangle + SPText *text = dynamic_cast<SPText *>(item); + g_assert(text != nullptr); + g_assert(text->style->shape_inside.set); + + Geom::Point const s = snap_knot_position(p, state); + + Inkscape::XML::Node* rectangle = text->get_first_rectangle(); + double x = 0.0; + double y = 0.0; + sp_repr_get_double (rectangle, "x", &x); + sp_repr_get_double (rectangle, "y", &y); + double width = s[Geom::X] - x; + double height = s[Geom::Y] - y; + sp_repr_set_svg_double (rectangle, "width", width); + sp_repr_set_svg_double (rectangle, "height", height); + + text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + text->updateRepr(); +} + TextKnotHolder::TextKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : KnotHolder(desktop, item, relhandler) { - TextKnotHolderEntityInlineSize *entity_inlinesize = new TextKnotHolderEntityInlineSize(); + SPText *text = dynamic_cast<SPText *>(item); + g_assert(text != nullptr); + + if (text->style->shape_inside.set) { + // 'shape-inside' + TextKnotHolderEntityShapeInside *entity_shapeinside = new TextKnotHolderEntityShapeInside(); + + entity_shapeinside->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Adjust the <b>rectangular</b> region of the text."), + SP_KNOT_SHAPE_DIAMOND, SP_KNOT_MODE_XOR); - entity_inlinesize->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, - _("Adjust the <b>inline size</b> (line length) of the text."), - SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); + entity.push_back(entity_shapeinside); - entity.push_back(entity_inlinesize); + } else { + // 'inline-size' or normal text + TextKnotHolderEntityInlineSize *entity_inlinesize = new TextKnotHolderEntityInlineSize(); + + entity_inlinesize->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Adjust the <b>inline size</b> (line length) of the text."), + SP_KNOT_SHAPE_DIAMOND, SP_KNOT_MODE_XOR); + + entity.push_back(entity_inlinesize); + } } |
