18#include <glibmm/i18n.h>
44 ~RectKnotHolder()
override =
default;;
50 ~Box3DKnotHolder()
override =
default;;
56 ~MarkerKnotHolder()
override =
default;;
62 ~ArcKnotHolder()
override =
default;;
68 ~StarKnotHolder()
override =
default;;
74 ~SpiralKnotHolder()
override =
default;;
80 ~OffsetKnotHolder()
override =
default;;
86 ~TextKnotHolder()
override =
default;;
92 ~FlowtextKnotHolder()
override =
default;;
98 ~MiscKnotHolder()
override =
default;;
105 auto knot_holder = std::make_unique<KnotHolder>(
desktop,
item);
107 item->getCurrentLPE()->addHandles(knot_holder.get(),
item);
108 for (
auto i : knot_holder->entity) {
109 i->knot->is_lpe =
true;
119 int edit_marker_mode)
121 std::unique_ptr<KnotHolder> knotholder;
123 if (is<SPRect>(
item)) {
124 knotholder = std::make_unique<RectKnotHolder>(
desktop,
item);
125 }
else if (is<SPBox3D>(
item)) {
126 knotholder = std::make_unique<Box3DKnotHolder>(
desktop,
item);
127 }
else if (is<SPMarker>(
item)) {
128 knotholder = std::make_unique<MarkerKnotHolder>(
desktop,
item, edit_rotation, edit_marker_mode);
129 }
else if (is<SPGenericEllipse>(
item)) {
130 knotholder = std::make_unique<ArcKnotHolder>(
desktop,
item);
131 }
else if (is<SPStar>(
item)) {
132 knotholder = std::make_unique<StarKnotHolder>(
desktop,
item);
133 }
else if (is<SPSpiral>(
item)) {
134 knotholder = std::make_unique<SpiralKnotHolder>(
desktop,
item);
135 }
else if (is<SPOffset>(
item)) {
136 knotholder = std::make_unique<OffsetKnotHolder>(
desktop,
item);
137 }
else if (
auto text = cast<SPText>(
item)) {
140 auto const text_children = text->childList(
false);
141 bool const is_on_path = std::any_of(text_children.begin(), text_children.end(), is<SPTextPath, SPObject>);
143 knotholder = std::make_unique<TextKnotHolder>(
desktop,
item);
146 auto flowtext = cast<SPFlowtext>(
item);
147 if (flowtext && flowtext->has_internal_frame()) {
148 knotholder = std::make_unique<FlowtextKnotHolder>(
desktop, flowtext->get_frame(
nullptr));
151 knotholder = std::make_unique<KnotHolder>(
desktop,
item);
152 knotholder->add_pattern_knotholder();
156 knotholder = std::make_unique<KnotHolder>(
desktop,
item);
158 knotholder->add_filter_knotholder();
165 auto lpe = cast<SPLPEItem>(
item);
167 lpe->getCurrentLPE() &&
168 lpe->getCurrentLPE()->isVisible() &&
169 lpe->getCurrentLPE()->providesKnotholder()) {
170 return make_lpe_knot_holder(lpe,
desktop);
226RectKnotHolderEntityRX::knot_get()
const
228 auto rect = cast<SPRect>(
item);
229 g_assert(rect !=
nullptr);
231 return Geom::Point(rect->x.computed + rect->width.computed - rect->rx.computed, rect->y.computed);
237 auto rect = cast<SPRect>(
item);
238 g_assert(rect !=
nullptr);
245 if (state & GDK_CONTROL_MASK) {
246 gdouble temp =
MIN(rect->height.computed, rect->width.computed) / 2.0;
247 rect->rx = rect->ry = CLAMP(rect->x.computed + rect->width.computed - s[
Geom::X], 0.0, temp);
249 rect->rx = CLAMP(rect->x.computed + rect->width.computed - s[
Geom::X], 0.0, rect->width.computed / 2.0);
254 rect->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
260 auto rect = cast<SPRect>(
item);
261 g_assert(rect !=
nullptr);
263 if (state & GDK_SHIFT_MASK) {
265 rect->getRepr()->removeAttribute(
"rx");
266 rect->getRepr()->removeAttribute(
"ry");
267 }
else if (state & GDK_CONTROL_MASK) {
269 rect->getRepr()->setAttribute(
"ry", rect->getRepr()->attribute(
"rx"));
275RectKnotHolderEntityRY::knot_get()
const
277 auto rect = cast<SPRect>(
item);
278 g_assert(rect !=
nullptr);
280 return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->ry.computed);
286 auto rect = cast<SPRect>(
item);
287 g_assert(rect !=
nullptr);
294 if (state & GDK_CONTROL_MASK) {
296 gdouble temp =
MIN(rect->height.computed, rect->width.computed) / 2.0;
297 rect->rx = rect->ry = CLAMP(s[
Geom::Y] - rect->y.computed, 0.0, temp);
299 if (!rect->rx._set || rect->rx.computed == 0) {
300 rect->ry = CLAMP(s[
Geom::Y] - rect->y.computed,
302 MIN(rect->height.computed / 2.0, rect->width.computed / 2.0));
304 rect->ry = CLAMP(s[
Geom::Y] - rect->y.computed,
306 rect->height.computed / 2.0);
312 rect->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
318 auto rect = cast<SPRect>(
item);
319 g_assert(rect !=
nullptr);
321 if (state & GDK_SHIFT_MASK) {
323 rect->getRepr()->removeAttribute(
"rx");
324 rect->getRepr()->removeAttribute(
"ry");
325 }
else if (state & GDK_CONTROL_MASK) {
327 rect->getRepr()->setAttribute(
"rx", rect->getRepr()->attribute(
"ry"));
331#define SGN(x) ((x)>0?1:((x)<0?-1:0))
345RectKnotHolderEntityWH::knot_get()
const
347 auto rect = cast<SPRect>(
item);
348 g_assert(rect !=
nullptr);
350 return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed);
356 auto rect = cast<SPRect>(
item);
357 g_assert(rect !=
nullptr);
361 if (state & GDK_CONTROL_MASK) {
367 gdouble ratio = (w_orig / h_orig);
373 Geom::Point p_handle(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed);
375 if (fabs(minx) > fabs(miny)) {
377 if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) {
383 rect->height =
MAX(h_orig + minx / ratio, 0);
390 rect->height =
MAX(h_orig, 0);
392 rect->width =
MAX(w_orig + minx, 0);
396 if (miny != 0 && fabs(minx/miny) > 0.5 * ratio && (SGN(minx) == SGN(miny))) {
402 rect->width =
MAX(w_orig + miny * ratio, 0);
409 rect->width =
MAX(w_orig, 0);
411 rect->height =
MAX(h_orig + miny, 0);
417 s = snap_knot_position(p, state);
418 rect->width =
MAX(s[
Geom::X] - rect->x.computed, 0);
419 rect->height =
MAX(s[
Geom::Y] - rect->y.computed, 0);
424 rect->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
430 set_internal(p,
origin, state);
435RectKnotHolderEntityXY::knot_get()
const
437 auto rect = cast<SPRect>(
item);
438 g_assert(rect !=
nullptr);
440 return Geom::Point(rect->x.computed, rect->y.computed);
446 auto rect = cast<SPRect>(
item);
447 g_assert(rect !=
nullptr);
450 gdouble opposite_x = (rect->x.computed + rect->width.computed);
451 gdouble opposite_y = (rect->y.computed + rect->height.computed);
458 Geom::Point p_handle(rect->x.computed, rect->y.computed);
464 if (state & GDK_CONTROL_MASK) {
466 gdouble ratio = (w_orig / h_orig);
468 if (fabs(minx) > fabs(miny)) {
470 if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) {
477 rect->height =
MAX(h_orig - minx / ratio, 0);
485 rect->height =
MAX(h_orig, 0);
488 rect->width =
MAX(w_orig - minx, 0);
491 if (miny != 0 && fabs(minx/miny) > 0.5 *ratio && (SGN(minx) == SGN(miny))) {
498 rect->width =
MAX(w_orig - miny * ratio, 0);
506 rect->width =
MAX(w_orig, 0);
509 rect->height =
MAX(h_orig - miny, 0);
514 s = snap_knot_position(p, state);
520 rect->width =
MAX(w_orig - minx, 0);
521 rect->height =
MAX(h_orig - miny, 0);
528 rect->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
532RectKnotHolderEntityCenter::knot_get()
const
534 auto rect = cast<SPRect>(
item);
535 g_assert(rect !=
nullptr);
537 return Geom::Point(rect->x.computed + (rect->width.computed / 2.), rect->y.computed + (rect->height.computed / 2.));
543 auto rect = cast<SPRect>(
item);
544 g_assert(rect !=
nullptr);
546 Geom::Point const s = snap_knot_position(p, state);
548 rect->x = s[
Geom::X] - (rect->width.computed / 2.);
549 rect->
y = s[
Geom::Y] - (rect->height.computed / 2.);
554 rect->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
560 RectKnotHolderEntityRX *entity_rx =
new RectKnotHolderEntityRX();
561 RectKnotHolderEntityRY *entity_ry =
new RectKnotHolderEntityRY();
562 RectKnotHolderEntityWH *entity_wh =
new RectKnotHolderEntityWH();
563 RectKnotHolderEntityXY *entity_xy =
new RectKnotHolderEntityXY();
564 RectKnotHolderEntityCenter *entity_center =
new RectKnotHolderEntityCenter();
567 _(
"Adjust the <b>horizontal rounding</b> radius; with <b>Ctrl</b> "
568 "to make the vertical radius the same"));
571 _(
"Adjust the <b>vertical rounding</b> radius; with <b>Ctrl</b> "
572 "to make the horizontal radius the same"));
575 _(
"Adjust the <b>width and height</b> of the rectangle; with <b>Ctrl</b> "
576 "to lock ratio or stretch in one dimension only"));
579 _(
"Adjust the <b>width and height</b> of the rectangle; with <b>Ctrl</b> "
580 "to lock ratio or stretch in one dimension only"));
583 _(
"Drag to move the rectangle"));
585 entity.push_back(entity_rx);
586 entity.push_back(entity_ry);
587 entity.push_back(entity_wh);
588 entity.push_back(entity_xy);
589 entity.push_back(entity_center);
591 add_pattern_knotholder();
592 add_hatch_knotholder();
607Box3DKnotHolderEntity::knot_get_generic(
SPItem *
item,
unsigned int knot_id)
const
609 auto box = cast<SPBox3D>(
item);
611 return box->get_corner_screen(knot_id);
618Box3DKnotHolderEntity::knot_set_generic(
SPItem *
item,
unsigned int knot_id,
Geom::Point const &new_pos,
unsigned int state)
620 Geom::Point const s = snap_knot_position(new_pos, state);
622 g_assert(
item !=
nullptr);
623 auto box = cast<SPBox3D>(
item);
624 g_assert(box !=
nullptr);
628 if ((knot_id < 4) != (state & GDK_SHIFT_MASK)) {
634 box->set_corner (knot_id, s * i2dt, movement, (state & GDK_CONTROL_MASK));
639class Box3DKnotHolderEntity0 :
public Box3DKnotHolderEntity {
646class Box3DKnotHolderEntity1 :
public Box3DKnotHolderEntity {
653class Box3DKnotHolderEntity2 :
public Box3DKnotHolderEntity {
660class Box3DKnotHolderEntity3 :
public Box3DKnotHolderEntity {
667class Box3DKnotHolderEntity4 :
public Box3DKnotHolderEntity {
674class Box3DKnotHolderEntity5 :
public Box3DKnotHolderEntity {
681class Box3DKnotHolderEntity6 :
public Box3DKnotHolderEntity {
688class Box3DKnotHolderEntity7 :
public Box3DKnotHolderEntity {
703Box3DKnotHolderEntity0::knot_get()
const
705 return knot_get_generic(
item, 0);
709Box3DKnotHolderEntity1::knot_get()
const
711 return knot_get_generic(
item, 1);
715Box3DKnotHolderEntity2::knot_get()
const
717 return knot_get_generic(
item, 2);
721Box3DKnotHolderEntity3::knot_get()
const
723 return knot_get_generic(
item, 3);
727Box3DKnotHolderEntity4::knot_get()
const
729 return knot_get_generic(
item, 4);
733Box3DKnotHolderEntity5::knot_get()
const
735 return knot_get_generic(
item, 5);
739Box3DKnotHolderEntity6::knot_get()
const
741 return knot_get_generic(
item, 6);
745Box3DKnotHolderEntity7::knot_get()
const
747 return knot_get_generic(
item, 7);
751Box3DKnotHolderEntityCenter::knot_get()
const
753 auto box = cast<SPBox3D>(
item);
755 return box->get_center_screen();
764 knot_set_generic(
item, 0, new_pos, state);
770 knot_set_generic(
item, 1, new_pos, state);
776 knot_set_generic(
item, 2, new_pos, state);
782 knot_set_generic(
item, 3, new_pos, state);
788 knot_set_generic(
item, 4, new_pos, state);
794 knot_set_generic(
item, 5, new_pos, state);
800 knot_set_generic(
item, 6, new_pos, state);
806 knot_set_generic(
item, 7, new_pos, state);
812 Geom::Point const s = snap_knot_position(new_pos, state);
814 auto box = cast<SPBox3D>(
item);
815 g_assert(box !=
nullptr);
819 state & GDK_CONTROL_MASK);
828 Box3DKnotHolderEntity0 *entity_corner0 =
new Box3DKnotHolderEntity0();
829 Box3DKnotHolderEntity1 *entity_corner1 =
new Box3DKnotHolderEntity1();
830 Box3DKnotHolderEntity2 *entity_corner2 =
new Box3DKnotHolderEntity2();
831 Box3DKnotHolderEntity3 *entity_corner3 =
new Box3DKnotHolderEntity3();
832 Box3DKnotHolderEntity4 *entity_corner4 =
new Box3DKnotHolderEntity4();
833 Box3DKnotHolderEntity5 *entity_corner5 =
new Box3DKnotHolderEntity5();
834 Box3DKnotHolderEntity6 *entity_corner6 =
new Box3DKnotHolderEntity6();
835 Box3DKnotHolderEntity7 *entity_corner7 =
new Box3DKnotHolderEntity7();
836 Box3DKnotHolderEntityCenter *entity_center =
new Box3DKnotHolderEntityCenter();
839 _(
"Resize box in X/Y direction; with <b>Shift</b> along the Z axis; "
840 "with <b>Ctrl</b> to constrain to the directions of edges or diagonals"));
843 _(
"Resize box in X/Y direction; with <b>Shift</b> along the Z axis; "
844 "with <b>Ctrl</b> to constrain to the directions of edges or diagonals"));
847 _(
"Resize box in X/Y direction; with <b>Shift</b> along the Z axis; "
848 "with <b>Ctrl</b> to constrain to the directions of edges or diagonals"));
851 _(
"Resize box in X/Y direction; with <b>Shift</b> along the Z axis; "
852 "with <b>Ctrl</b> to constrain to the directions of edges or diagonals"));
855 _(
"Resize box along the Z axis; with <b>Shift</b> in X/Y direction; "
856 "with <b>Ctrl</b> to constrain to the directions of edges or diagonals"));
859 _(
"Resize box along the Z axis; with <b>Shift</b> in X/Y direction; "
860 "with <b>Ctrl</b> to constrain to the directions of edges or diagonals"));
863 _(
"Resize box along the Z axis; with <b>Shift</b> in X/Y direction; "
864 "with <b>Ctrl</b> to constrain to the directions of edges or diagonals"));
867 _(
"Resize box along the Z axis; with <b>Shift</b> in X/Y direction; "
868 "with <b>Ctrl</b> to constrain to the directions of edges or diagonals"));
871 _(
"Move the box in perspective"));
873 entity.push_back(entity_corner0);
874 entity.push_back(entity_corner1);
875 entity.push_back(entity_corner2);
876 entity.push_back(entity_corner3);
877 entity.push_back(entity_corner4);
878 entity.push_back(entity_corner5);
879 entity.push_back(entity_corner6);
880 entity.push_back(entity_corner7);
881 entity.push_back(entity_center);
883 add_pattern_knotholder();
884 add_hatch_knotholder();
893 auto sp_marker = cast<SPMarker>(
item);
894 g_assert(sp_marker !=
nullptr);
896 return ((sp_marker->viewBox.width() != 0) ? sp_marker->markerWidth.computed/sp_marker->viewBox.width() : 1.0);
902 auto sp_marker = cast<SPMarker>(
item);
903 g_assert(sp_marker !=
nullptr);
905 return ((sp_marker->viewBox.height() != 0) ? sp_marker->markerHeight.computed/sp_marker->viewBox.height() : 1.0);
915 auto sp_marker = cast<SPMarker>(
item);
916 g_assert(sp_marker !=
nullptr);
932 auto sp_marker = cast<SPMarker>(
item);
935 g_assert(sp_marker !=
nullptr);
936 g_assert(doc !=
nullptr);
941 for (
auto *i :
items) {
942 auto item = cast<SPItem>(i);
957 double _edit_rotation = 0.0;
958 int _edit_marker_mode = -1;
960 MarkerKnotHolderEntityReference(
double edit_rotation,
int edit_marker_mode)
961 : _edit_rotation(edit_rotation),
962 _edit_marker_mode(edit_marker_mode)
973MarkerKnotHolderEntityReference::knot_get()
const
975 auto sp_marker = cast<SPMarker>(
item);
976 g_assert(sp_marker !=
nullptr);
987 auto sp_marker = cast<SPMarker>(
item);
988 g_assert(sp_marker !=
nullptr);
995 sp_marker->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1002 double _edit_rotation = 0.0;
1003 int _edit_marker_mode = -1;
1005 bool originals_set =
false;
1008 double original_center_angle = 0;
1009 double original_radius = 0;
1012 MarkerKnotHolderEntityOrient(
double edit_rotation,
int edit_marker_mode)
1013 : _edit_rotation(edit_rotation),
1014 _edit_marker_mode(edit_marker_mode)
1028 originals_set =
false;
1032MarkerKnotHolderEntityOrient::knot_get()
const
1034 auto sp_marker = cast<SPMarker>(
item);
1035 g_assert(sp_marker !=
nullptr);
1046 if(!originals_set) {
1047 auto sp_marker = cast<SPMarker>(
item);
1048 g_assert(sp_marker !=
nullptr);
1057 sp_marker->orient_set =
true;
1069 original_center_angle =
atan2(
1070 sp_marker->markerHeight.computed - sp_marker->markerHeight.computed/2,
1071 sp_marker->markerWidth.computed - sp_marker->markerWidth.computed/2
1074 original_radius =
L2(original_center);
1075 originals_set =
true;
1078 set_internal(p,
origin, state);
1085 auto sp_marker = cast<SPMarker>(
item);
1086 g_assert(sp_marker !=
nullptr);
1090 new_angle = new_angle + _edit_rotation + original_center_angle;
1092 double axis_angle = -((
atan2(original_center) * 180.0/M_PI) + _edit_rotation);
1094 sp_marker->orient = new_angle;
1096 sp_marker->orient_set =
true;
1105 sp_marker->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1112 double _edit_rotation = 0.0;
1113 int _edit_marker_mode = -1;
1122 bool originals_set =
false;
1124 double original_scaleX = 1;
1125 double original_scaleY = 1;
1127 double original_refX = 0;
1128 double original_refY = 0;
1130 double original_width = 0;
1131 double original_height = 0;
1133 MarkerKnotHolderEntityScale(
double edit_rotation,
int edit_marker_mode,
int x_Sign,
int y_Sign)
1134 : _edit_rotation(edit_rotation),
1135 _edit_marker_mode(edit_marker_mode),
1152 originals_set =
false;
1156MarkerKnotHolderEntityScale::knot_get()
const
1158 auto sp_marker = cast<SPMarker>(
item);
1159 g_assert(sp_marker !=
nullptr);
1171 if(!originals_set) {
1173 auto sp_marker = cast<SPMarker>(
item);
1174 g_assert(sp_marker !=
nullptr);
1179 original_refX = sp_marker->refX.computed;
1180 original_refY = sp_marker->refY.computed;
1182 original_width = sp_marker->viewBox.width();
1183 original_height = sp_marker->viewBox.height();
1185 originals_set =
true;
1188 set_internal(p,
origin, state);
1196 auto sp_marker = cast<SPMarker>(
item);
1197 g_assert(sp_marker !=
nullptr);
1204 adjusted_origin = adjusted_origin
1208 adjusted_p = adjusted_p
1214 adjusted_origin = adjusted_origin
1218 adjusted_p = adjusted_p
1224 double orig_width = _x_Sign*((original_width * original_scaleX)/2);
1225 double orig_height = _y_Sign*((original_height * original_scaleY)/2);
1230 double adjusted_scaleX = 0.0;
1231 double adjusted_scaleY = 0.0;
1233 adjusted_scaleX = (dx/orig_width) + 1;
1234 adjusted_scaleY = (dy/orig_height) + 1;
1237 if(state & GDK_CONTROL_MASK) {
1238 adjusted_scaleX = fabs(adjusted_scaleX);
1239 adjusted_scaleY = fabs(adjusted_scaleY);
1242 double dx_area = (sp_marker->viewBox.width()*adjusted_scaleX) * (sp_marker->viewBox.height()*adjusted_scaleX);
1243 double dy_area = (sp_marker->viewBox.width()*adjusted_scaleY) * (sp_marker->viewBox.height()*adjusted_scaleY);
1245 if (dy_area > dx_area) {
1246 adjusted_scaleX = adjusted_scaleY;
1247 }
else if (dx_area > dy_area) {
1248 adjusted_scaleY = adjusted_scaleX;
1251 adjusted_scaleX = adjusted_scaleX * original_scaleX;
1252 adjusted_scaleY = adjusted_scaleY * original_scaleY;
1254 sp_marker->markerWidth = sp_marker->viewBox.width() * adjusted_scaleX;
1255 sp_marker->markerHeight = sp_marker->viewBox.height() * adjusted_scaleY;
1257 sp_marker->refX = ((original_refX * original_scaleX)/adjusted_scaleX) - ((
getMarkerBounds(
item,
desktop).
min()[
Geom::X] + sp_marker->viewBox.width()/2) * (original_scaleX/adjusted_scaleX - 1));
1258 sp_marker->refY = ((original_refY * original_scaleY)/adjusted_scaleY) - ((
getMarkerBounds(
item,
desktop).
min()[
Geom::Y] + sp_marker->viewBox.height()/2) * (original_scaleY/adjusted_scaleY - 1));
1261 adjusted_scaleX = adjusted_scaleX * original_scaleX;
1262 adjusted_scaleY = adjusted_scaleY * original_scaleY;
1266 sp_marker->setAttribute(
"preserveAspectRatio",
"none");
1269 if(adjusted_scaleX > 0.0 && adjusted_scaleY > 0.0) {
1270 sp_marker->markerWidth = sp_marker->viewBox.width() * adjusted_scaleX;
1271 sp_marker->markerHeight = sp_marker->viewBox.height() * adjusted_scaleY;
1273 sp_marker->refX = ((original_refX * original_scaleX)/adjusted_scaleX) - ((
getMarkerBounds(
item,
desktop).
min()[
Geom::X] + sp_marker->viewBox.width()/2) * (original_scaleX/adjusted_scaleX - 1));
1274 sp_marker->refY = ((original_refY * original_scaleY)/adjusted_scaleY) - ((
getMarkerBounds(
item,
desktop).
min()[
Geom::Y] + sp_marker->viewBox.height()/2) * (original_scaleY/adjusted_scaleY - 1));
1278 sp_marker->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
1281class MarkerKnotHolderEntityScale2 :
public MarkerKnotHolderEntityScale {
1283 MarkerKnotHolderEntityScale2(
double edit_rotation,
int edit_marker_mode,
int x_Sign,
int y_Sign)
1284 : MarkerKnotHolderEntityScale(edit_rotation, edit_marker_mode, x_Sign, y_Sign)
1292MarkerKnotHolderEntityScale2::knot_get()
const
1294 auto sp_marker = cast<SPMarker>(
item);
1295 g_assert(sp_marker !=
nullptr);
1304class MarkerKnotHolderEntityScale3 :
public MarkerKnotHolderEntityScale {
1306 MarkerKnotHolderEntityScale3(
double edit_rotation,
int edit_marker_mode,
int x_Sign,
int y_Sign)
1307 : MarkerKnotHolderEntityScale(edit_rotation, edit_marker_mode, x_Sign, y_Sign)
1315MarkerKnotHolderEntityScale3::knot_get()
const
1317 auto sp_marker = cast<SPMarker>(
item);
1318 g_assert(sp_marker !=
nullptr);
1329 MarkerKnotHolderEntityReference *entity_reference =
new MarkerKnotHolderEntityReference(edit_rotation, edit_marker_mode);
1330 MarkerKnotHolderEntityOrient *entity_orient =
new MarkerKnotHolderEntityOrient(edit_rotation, edit_marker_mode);
1332 MarkerKnotHolderEntityScale *entity_scale =
new MarkerKnotHolderEntityScale(edit_rotation, edit_marker_mode, 1, 1);
1334 MarkerKnotHolderEntityScale2 *entity_scale2 =
new MarkerKnotHolderEntityScale2(edit_rotation, edit_marker_mode, -1, -1);
1335 MarkerKnotHolderEntityScale3 *entity_scale3 =
new MarkerKnotHolderEntityScale3(edit_rotation, edit_marker_mode, -1, 1);
1338 _(
"Drag to adjust the refX/refY position of the marker"));
1341 _(
"Adjust marker orientation through rotation"));
1344 _(
"Adjust the <b>size</b> of the marker"));
1347 _(
"Adjust the <b>size</b> of the marker"));
1350 _(
"Adjust the <b>size</b> of the marker"));
1352 entity.push_back(entity_reference);
1353 entity.push_back(entity_orient);
1354 entity.push_back(entity_scale);
1355 entity.push_back(entity_scale2);
1356 entity.push_back(entity_scale3);
1358 add_pattern_knotholder();
1359 add_hatch_knotholder();
1369 void knot_click(
unsigned int state)
override;
1377 void knot_click(
unsigned int state)
override;
1385 void knot_click(
unsigned int state)
override;
1393 void knot_click(
unsigned int state)
override;
1415 gdouble s = dx * dx + dy * dy;
1419 if (s < 0.75)
return 1;
1420 if (s > 1.25)
return -1;
1429 auto arc = cast<SPGenericEllipse>(
item);
1430 g_assert(arc !=
nullptr);
1433 if(side != 0) { arc->setArcType( (side == -1) ?
1438 Geom::Scale sc(arc->rx.computed, arc->ry.computed);
1443 if ((state & GDK_CONTROL_MASK) && snaps) {
1444 double snaps_radian = M_PI/snaps;
1445 arc->start = std::round(arc->start/snaps_radian) * snaps_radian;
1447 if (state & GDK_SHIFT_MASK) {
1452 arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1456ArcKnotHolderEntityStart::knot_get()
const
1459 g_assert(ge !=
nullptr);
1467 auto ge = cast<SPGenericEllipse>(
item);
1468 g_assert(ge !=
nullptr);
1470 if (state & GDK_SHIFT_MASK) {
1481 auto arc = cast<SPGenericEllipse>(
item);
1482 g_assert(arc !=
nullptr);
1485 if(side != 0) { arc->setArcType( (side == -1) ?
1490 Geom::Scale sc(arc->rx.computed, arc->ry.computed);
1495 if ((state & GDK_CONTROL_MASK) && snaps) {
1496 double snaps_radian = M_PI/snaps;
1497 arc->end = std::round(arc->end/snaps_radian) * snaps_radian;
1499 if (state & GDK_SHIFT_MASK) {
1504 arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1508ArcKnotHolderEntityEnd::knot_get()
const
1511 g_assert(ge !=
nullptr);
1520 auto ge = cast<SPGenericEllipse>(
item);
1521 g_assert(ge !=
nullptr);
1523 if (state & GDK_SHIFT_MASK) {
1533 auto ge = cast<SPGenericEllipse>(
item);
1534 g_assert(ge !=
nullptr);
1536 Geom::Point const s = snap_knot_position(p, state);
1540 if ( state & GDK_CONTROL_MASK ) {
1548ArcKnotHolderEntityRX::knot_get()
const
1551 g_assert(ge !=
nullptr);
1559 auto ge = cast<SPGenericEllipse>(
item);
1560 g_assert(ge !=
nullptr);
1562 if (state & GDK_CONTROL_MASK) {
1571 auto ge = cast<SPGenericEllipse>(
item);
1572 g_assert(ge !=
nullptr);
1574 Geom::Point const s = snap_knot_position(p, state);
1578 if ( state & GDK_CONTROL_MASK ) {
1586ArcKnotHolderEntityRY::knot_get()
const
1589 g_assert(ge !=
nullptr);
1597 auto ge = cast<SPGenericEllipse>(
item);
1598 g_assert(ge !=
nullptr);
1600 if (state & GDK_CONTROL_MASK) {
1609 auto ge = cast<SPGenericEllipse>(
item);
1610 g_assert(ge !=
nullptr);
1612 Geom::Point const s = snap_knot_position(p, state);
1621ArcKnotHolderEntityCenter::knot_get()
const
1624 g_assert(ge !=
nullptr);
1632 ArcKnotHolderEntityRX *entity_rx =
new ArcKnotHolderEntityRX();
1633 ArcKnotHolderEntityRY *entity_ry =
new ArcKnotHolderEntityRY();
1634 ArcKnotHolderEntityStart *entity_start =
new ArcKnotHolderEntityStart();
1635 ArcKnotHolderEntityEnd *entity_end =
new ArcKnotHolderEntityEnd();
1636 ArcKnotHolderEntityCenter *entity_center =
new ArcKnotHolderEntityCenter();
1639 _(
"Adjust ellipse <b>width</b>, with <b>Ctrl</b> to make circle"));
1642 _(
"Adjust ellipse <b>height</b>, with <b>Ctrl</b> to make circle"));
1645 _(
"Position the <b>start point</b> of the arc or segment; with <b>Shift</b> to move "
1646 "with <b>end point</b>; with <b>Ctrl</b> to snap angle; drag <b>inside</b> the "
1647 "ellipse for arc, <b>outside</b> for segment"));
1650 _(
"Position the <b>end point</b> of the arc or segment; with <b>Shift</b> to move "
1651 "with <b>start point</b>; with <b>Ctrl</b> to snap angle; drag <b>inside</b> the "
1652 "ellipse for arc, <b>outside</b> for segment"));
1655 _(
"Drag to move the ellipse"));
1657 entity.push_back(entity_rx);
1658 entity.push_back(entity_ry);
1659 entity.push_back(entity_start);
1660 entity.push_back(entity_end);
1661 entity.push_back(entity_center);
1663 add_pattern_knotholder();
1664 add_hatch_knotholder();
1674 void knot_click(
unsigned int state)
override;
1682 void knot_click(
unsigned int state)
override;
1695 auto star = cast<SPStar>(
item);
1696 g_assert(star !=
nullptr);
1698 Geom::Point const s = snap_knot_position(p, state);
1702 double arg1 =
atan2(d);
1703 double darg1 = arg1 - star->arg[0];
1705 if (state & GDK_ALT_MASK) {
1706 star->randomized = darg1/(star->arg[0] - star->arg[1]);
1707 }
else if (state & GDK_SHIFT_MASK) {
1708 star->rounded = darg1/(star->arg[0] - star->arg[1]);
1709 }
else if (state & GDK_CONTROL_MASK) {
1713 star->arg[0] = arg1;
1714 star->arg[1] += darg1;
1716 star->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1722 auto star = cast<SPStar>(
item);
1723 g_assert(star !=
nullptr);
1725 Geom::Point const s = snap_knot_position(p, state);
1727 if (star->flatsided ==
false) {
1730 double arg1 =
atan2(d);
1731 double darg1 = arg1 - star->arg[1];
1733 if (state & GDK_ALT_MASK) {
1734 star->randomized = darg1/(star->arg[0] - star->arg[1]);
1735 }
else if (state & GDK_SHIFT_MASK) {
1736 star->rounded = fabs(darg1/(star->arg[0] - star->arg[1]));
1737 }
else if (state & GDK_CONTROL_MASK) {
1739 star->arg[1] = star->arg[0] + M_PI / star->sides;
1743 star->arg[1] =
atan2(d);
1745 star->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1752 auto star = cast<SPStar>(
item);
1753 g_assert(star !=
nullptr);
1755 star->center = snap_knot_position(p, state);
1761StarKnotHolderEntity1::knot_get()
const
1763 g_assert(
item !=
nullptr);
1766 g_assert(star !=
nullptr);
1773StarKnotHolderEntity2::knot_get()
const
1775 g_assert(
item !=
nullptr);
1778 g_assert(star !=
nullptr);
1784StarKnotHolderEntityCenter::knot_get()
const
1786 g_assert(
item !=
nullptr);
1789 g_assert(star !=
nullptr);
1797 auto star = cast<SPStar>(
item);
1798 g_assert(star !=
nullptr);
1800 if (state & GDK_ALT_MASK) {
1801 star->randomized = 0;
1803 }
else if (state & GDK_SHIFT_MASK) {
1806 }
else if (state & GDK_CONTROL_MASK) {
1807 star->arg[1] = star->arg[0] + M_PI / star->sides;
1827 auto star = cast<SPStar>(
item);
1828 g_assert(
item !=
nullptr);
1830 StarKnotHolderEntity1 *entity1 =
new StarKnotHolderEntity1();
1832 _(
"Adjust the <b>tip radius</b> of the star or polygon; "
1833 "with <b>Shift</b> to round; with <b>Alt</b> to randomize"));
1835 entity.push_back(entity1);
1837 if (star->flatsided ==
false) {
1838 StarKnotHolderEntity2 *entity2 =
new StarKnotHolderEntity2();
1840 _(
"Adjust the <b>base radius</b> of the star; with <b>Ctrl</b> to keep star rays "
1841 "radial (no skew); with <b>Shift</b> to round; with <b>Alt</b> to randomize"));
1842 entity.push_back(entity2);
1845 StarKnotHolderEntityCenter *entity_center =
new StarKnotHolderEntityCenter();
1847 _(
"Drag to move the star"));
1848 entity.push_back(entity_center);
1850 add_pattern_knotholder();
1851 add_hatch_knotholder();
1861 void knot_click(
unsigned int state)
override;
1889 int snaps = prefs->
getInt(
"/options/rotationsnapsperpi/value", 12);
1891 auto spiral = cast<SPSpiral>(
item);
1892 g_assert(spiral !=
nullptr);
1894 gdouble dx = p[
Geom::X] - spiral->cx;
1895 gdouble dy = p[
Geom::Y] - spiral->cy;
1899 if (state & GDK_ALT_MASK) {
1901 if (spiral->rad > 0) {
1902 double exp_delta = 0.1*moved_y/(spiral->rad);
1903 spiral->exp += exp_delta;
1904 if (spiral->exp < 1e-3)
1910 spiral->getPolar(spiral->t0,
nullptr, &arg_t0);
1912 gdouble arg_tmp =
atan2(dy, dx) - arg_t0;
1913 gdouble arg_t0_new = arg_tmp -
floor((arg_tmp+M_PI)/(2.0*M_PI))*2.0*M_PI + arg_t0;
1914 spiral->t0 = (arg_t0_new - spiral->arg) / (2.0*M_PI*spiral->revo);
1917 if ( ( state & GDK_CONTROL_MASK )
1918 && ( fabs(spiral->revo) > SP_EPSILON_2 )
1919 && ( snaps != 0 ) ) {
1920 gdouble arg = 2.0*M_PI*spiral->revo*spiral->t0 + spiral->arg;
1921 double snaps_radian = M_PI/snaps;
1922 spiral->t0 = (std::round(arg/snaps_radian)*snaps_radian - spiral->arg)/(2.0*M_PI*spiral->revo);
1925 spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999);
1928 spiral->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1940 int snaps = prefs->
getInt(
"/options/rotationsnapsperpi/value", 12);
1942 auto spiral = cast<SPSpiral>(
item);
1943 g_assert(spiral !=
nullptr);
1945 gdouble dx = p[
Geom::X] - spiral->cx;
1946 gdouble dy = p[
Geom::Y] - spiral->cy;
1948 if (state & GDK_SHIFT_MASK) {
1949 spiral->arg =
atan2(dy, dx) - 2.0*M_PI*spiral->revo;
1950 if (!(state & GDK_ALT_MASK)) {
1952 spiral->rad =
MAX(hypot(dx, dy), 0.001);
1954 if ( ( state & GDK_CONTROL_MASK ) && snaps ) {
1955 double snaps_radian = M_PI/snaps;
1956 spiral->arg = std::round(spiral->arg/snaps_radian) * snaps_radian;
1961 spiral->getPolar(1,
nullptr, &arg_1);
1964 static double _2PI = 2.0 * M_PI;
1965 double arg_r = arg_1 - std::round(arg_1/_2PI) * _2PI;
1968 double mouse_angle =
atan2(dy, dx);
1969 if (mouse_angle < 0)
1970 mouse_angle += _2PI;
1973 if ( ( state & GDK_CONTROL_MASK ) && snaps ) {
1974 double snaps_radian = M_PI/snaps;
1975 mouse_angle = std::round(mouse_angle/snaps_radian) * snaps_radian;
1979 double diff = mouse_angle - arg_r;
1982 else if (diff < -M_PI)
1987 double t_temp = ((arg_1 + diff) - spiral->arg)/(_2PI*spiral->revo);
1990 if (t_temp > spiral->t0)
1991 spiral->getPolar(t_temp, &rad_new,
nullptr);
1994 spiral->revo += diff/(2*M_PI);
1995 if (spiral->revo < 1e-3)
1996 spiral->revo = 1e-3;
1999 if (!(state & GDK_ALT_MASK) && rad_new > 1e-3 && rad_new/spiral->rad < 2) {
2002 spiral->getPolar(spiral->t0, &r0,
nullptr);
2003 spiral->rad = rad_new;
2004 spiral->t0 =
pow(r0 / spiral->rad, 1.0/spiral->exp);
2006 if (!std::isfinite(spiral->t0)) spiral->t0 = 0.0;
2007 spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999);
2010 spiral->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
2016 auto spiral = cast<SPSpiral>(
item);
2017 g_assert(spiral !=
nullptr);
2019 Geom::Point const s = snap_knot_position(p, state);
2024 spiral->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
2028SpiralKnotHolderEntityInner::knot_get()
const
2031 g_assert(spiral !=
nullptr);
2033 return spiral->
getXY(spiral->
t0);
2037SpiralKnotHolderEntityOuter::knot_get()
const
2040 g_assert(spiral !=
nullptr);
2042 return spiral->
getXY(1.0);
2046SpiralKnotHolderEntityCenter::knot_get()
const
2049 g_assert(spiral !=
nullptr);
2057 auto spiral = cast<SPSpiral>(
item);
2058 g_assert(spiral !=
nullptr);
2060 if (state & GDK_ALT_MASK) {
2063 }
else if (state & GDK_SHIFT_MASK) {
2072 SpiralKnotHolderEntityCenter *entity_center =
new SpiralKnotHolderEntityCenter();
2073 SpiralKnotHolderEntityInner *entity_inner =
new SpiralKnotHolderEntityInner();
2074 SpiralKnotHolderEntityOuter *entity_outer =
new SpiralKnotHolderEntityOuter();
2089 _(
"Drag to move the spiral"));
2092 _(
"Roll/unroll the spiral from <b>inside</b>; with <b>Ctrl</b> to snap angle; "
2093 "with <b>Alt</b> to converge/diverge"));
2096 _(
"Roll/unroll the spiral from <b>outside</b>; with <b>Ctrl</b> to snap angle; "
2097 "with <b>Shift</b> to scale/rotate; with <b>Alt</b> to lock radius"));
2099 entity.push_back(entity_center);
2100 entity.push_back(entity_inner);
2101 entity.push_back(entity_outer);
2103 add_pattern_knotholder();
2104 add_hatch_knotholder();
2120 g_assert(
offset !=
nullptr);
2122 Geom::Point const p_snapped = snap_knot_position(p, state);
2125 offset->knot = p_snapped;
2128 offset->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
2133OffsetKnotHolderEntity::knot_get()
const
2136 g_assert(
offset !=
nullptr);
2146 OffsetKnotHolderEntity *entity_offset =
new OffsetKnotHolderEntity();
2148 _(
"Adjust the <b>offset distance</b>"));
2149 entity.push_back(entity_offset);
2151 add_pattern_knotholder();
2152 add_hatch_knotholder();
2162 void knot_click(
unsigned int state)
override;
2166TextKnotHolderEntityInlineSize::knot_get()
const
2168 auto text = cast<SPText>(
item);
2169 g_assert(text !=
nullptr);
2175 unsigned direction = style->
direction.computed;
2179 if (text->has_inline_size()) {
2248 auto text = cast<SPText>(
item);
2249 g_assert(text !=
nullptr);
2254 unsigned direction = style->
direction.computed;
2256 Geom::Point const s = snap_knot_position(p, state);
2273 std::cerr <<
"TextKnotHolderEntityInlinSize: Should not be reached!" << std::endl;
2295 text->style->inline_size.setDouble(
size);
2296 text->style->inline_size.set =
true;
2299 text->style->white_space.read(
"pre");
2300 text->style->white_space.set =
true;
2303 text->sodipodi_to_newline();
2305 text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
2313 auto text = cast<SPText>(
item);
2314 g_assert(text !=
nullptr);
2316 if (state & GDK_CONTROL_MASK) {
2318 text->style->inline_size.clear();
2319 text->remove_svg11_fallback();
2320 text->newline_to_sodipodi();
2322 text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
2338TextKnotHolderEntityShapePadding::knot_get()
const
2340 auto text = cast<SPText>(
item);
2341 g_assert(text !=
nullptr);
2344 if (!text->has_shape_inside()) {
2348 auto shape = text->get_first_shape_dependency();
2355 corner = (*bounds).
corner(1);
2356 if (text->style->shape_padding.set) {
2357 auto padding = text->style->shape_padding.computed;
2360 corner *= shape->transform;
2369 auto text = cast<SPText>(
item);
2370 g_assert(text !=
nullptr);
2371 if (!text->has_shape_inside()) {
2375 if (
auto shape = text->get_first_shape_dependency()) {
2377 auto bounds = *optbounds;
2378 Geom::Point const point_a = snap_knot_position(p, state);
2379 Geom::Point point_b = point_a * shape->transform.inverse();
2381 double padding = 0.0;
2387 if (padding >= 0.0) {
2390 text->style->shape_padding.read(os.
str().c_str());
2392 text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
2408 void set_shape(
SPShape *shape) { linked_shape = shape; }
2413TextKnotHolderEntityShapeMargin::knot_get()
const
2416 if (linked_shape ==
nullptr)
return corner;
2420 corner = (*bounds).corner(1);
2421 if (linked_shape->style->shape_margin.set) {
2422 auto margin = linked_shape->style->shape_margin.computed;
2425 corner *= linked_shape->transform;
2433 g_assert(linked_shape !=
nullptr);
2437 Geom::Point const point_a = snap_knot_position(p, state);
2438 Geom::Point point_b = point_a * linked_shape->transform.inverse();
2445 linked_shape->style->shape_margin.read(os.
str().c_str());
2447 linked_shape->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
2448 linked_shape->updateRepr();
2464TextKnotHolderEntityShapeInside::knot_get()
const
2467 auto text = cast<SPText>(
item);
2468 g_assert(text !=
nullptr);
2471 if (text->has_shape_inside()) {
2474 p = (*frame).corner(2);
2476 std::cerr <<
"TextKnotHolderEntityShapeInside::knot_get(): no frame!" << std::endl;
2486 auto text = cast<SPText>(
item);
2487 g_assert(text !=
nullptr);
2489 Geom::Point const s = snap_knot_position(p, state);
2501 text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
2508 auto text = cast<SPText>(
item);
2509 g_assert(text !=
nullptr);
2511 if (text->has_shape_inside()) {
2514 if (text->get_first_rectangle()) {
2515 auto entity_shapeinside =
new TextKnotHolderEntityShapeInside();
2517 _(
"Adjust the <b>rectangular</b> region of the text."));
2518 entity.push_back(entity_shapeinside);
2521 if (text->get_first_shape_dependency()) {
2522 auto entity_shapepadding =
new TextKnotHolderEntityShapePadding();
2524 _(
"Adjust the text <b>shape padding</b>."));
2525 entity.push_back(entity_shapepadding);
2530 if (text->style->shape_subtract.set) {
2531 for (
auto *href : text->style->shape_subtract.hrefs) {
2532 if (
auto shape = href->getObject()) {
2533 auto entity_shapemargin =
new TextKnotHolderEntityShapeMargin();
2535 _(
"Adjust the shape's <b>text margin</b>."));
2536 entity_shapemargin->set_shape(shape);
2537 entity_shapemargin->update_knot();
2538 entity.push_back(entity_shapemargin);
2545 TextKnotHolderEntityInlineSize *entity_inlinesize =
new TextKnotHolderEntityInlineSize();
2548 _(
"Adjust the <b>inline size</b> (line length) of the text."));
2549 entity.push_back(entity_inlinesize);
2552 add_pattern_knotholder();
2553 add_hatch_knotholder();
2560class FlowtextKnotHolderEntity :
public RectKnotHolderEntityWH {
2567FlowtextKnotHolderEntity::knot_get()
const
2570 g_assert(rect !=
nullptr);
2578 set_internal(p,
origin, state);
2584 g_assert(
item !=
nullptr);
2586 FlowtextKnotHolderEntity *entity_flowtext =
new FlowtextKnotHolderEntity();
2588 _(
"Drag to resize the <b>flowed text frame</b>"));
2589 entity.push_back(entity_flowtext);
3x3 matrix representing an affine transformation.
void unionWith(CRect const &b)
Enlarge the rectangle to contain the argument.
CPoint midpoint() const
Get the point in the geometric center of the rectangle.
CPoint min() const
Get the corner of the rectangle with smallest coordinate values.
CPoint corner(unsigned i) const
Return the n-th corner of the rectangle.
Axis-aligned rectangle that can be empty.
Two-dimensional point that doubles as a vector.
constexpr Coord y() const noexcept
constexpr Coord x() const noexcept
Axis aligned, non-empty rectangle.
static Rotate from_degrees(Coord deg)
Construct a rotation from its angle in degrees.
A thin wrapper around std::ostringstream, but writing floating point numbers in the format required b...
Preference storage class.
static Preferences * get()
Access the singleton Preferences object.
int getInt(Glib::ustring const &pref_path, int def=0)
Retrieve an integer.
Interface for refcounted XML nodes.
double getAttributeDouble(Util::const_char_ptr key, double default_value=0.0) const
bool setAttributeSvgDouble(Util::const_char_ptr key, double val)
For attributes where an exponent is allowed.
KnotHolderEntity definition.
virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned state)=0
virtual Geom::Point knot_get() const =0
virtual void knot_ungrabbed(Geom::Point const &p, Geom::Point const &origin, unsigned state)=0
virtual void knot_click(unsigned)
To do: update description of desktop.
SPDocument * getDocument() const
Typed SVG document implementation.
const Geom::Affine & dt2doc() const
Desktop to document coordinate transformation.
Geom::Point getPointAtAngle(double arg) const
Base class for visual SVG elements.
Geom::Affine i2dt_affine() const
Returns the transformation from item to desktop coords.
Geom::OptRect desktopVisualBounds() const
Get item's visual bbox in desktop coordinate system.
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
Inkscape::XML::Node * updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT)
Updates the object's repr based on the object's state.
void requestDisplayUpdate(unsigned int flags)
Queues an deferred update of this object's display.
Base class for shapes, including <path> element.
float exp
Spiral expansion factor.
Geom::Point getXY(double t) const
Return one of the points on the spiral.
SPPaintServer * getFillPaintServer()
T< SPAttr::FILL, SPIPaint > fill
fill
T< SPAttr::STROKE, SPIPaint > stroke
stroke
SPPaintServer * getStrokePaintServer()
T< SPAttr::DIRECTION, SPIEnum< SPCSSDirection > > direction
text direction (svg1.1)
T< SPAttr::INLINE_SIZE, SPILength > inline_size
T< SPAttr::TEXT_ANCHOR, SPIEnum< SPTextAnchor > > text_anchor
Anchor of the text (svg1.1 10.9.1)
T< SPAttr::WRITING_MODE, SPIEnum< SPCSSWritingMode > > writing_mode
Writing mode (svg1.1 10.7.2, CSS Writing Modes 3)
TODO: insert short description here.
Editable view implementation.
constexpr Coord infinity()
Get a value representing infinity.
auto floor(Geom::Rect const &rect)
Perspective line for 3D perspectives.
SBasisN< n > cos(LinearN< n > bo, int k)
double atan2(Point const &p)
SBasis L2(D2< SBasis > const &a, unsigned k)
Piecewise< SBasis > min(SBasis const &f, SBasis const &g)
Return the more negative of the two functions pointwise.
SBasisN< n > sin(LinearN< n > bo, int k)
Point abs(Point const &b)
std::unique_ptr< KnotHolder > create_LPE_knot_holder(SPItem *item, SPDesktop *desktop)
std::unique_ptr< KnotHolder > create_knot_holder(SPItem *item, SPDesktop *desktop, double edit_rotation, int edit_marker_mode)
Helper class to stream background task notifications as a series of messages.
@ CANVAS_ITEM_CTRL_TYPE_SIZER
@ CANVAS_ITEM_CTRL_TYPE_MARKER
@ CANVAS_ITEM_CTRL_TYPE_SHAPER
@ CANVAS_ITEM_CTRL_TYPE_ROTATE
Singleton class to access the preferences file in a convenient way.
double getMarkerYScale(SPItem *item)
Geom::Rect getMarkerBounds(SPItem *item, SPDesktop *desktop)
double getMarkerXScale(SPItem *item)
static void sp_star_knot_click(SPItem *item, unsigned int state)
Geom::Affine getMarkerRotation(SPItem *item, double edit_rotation, int edit_marker_mode, bool reverse=false)
static void sp_rect_clamp_radii(SPRect *rect)
static gint sp_genericellipse_side(SPGenericEllipse *ellipse, Geom::Point const &p)
@ SP_GENERIC_ELLIPSE_ARC_TYPE_SLICE
@ SP_GENERIC_ELLIPSE_ARC_TYPE_ARC
TODO: insert short description here.
Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx.
@ MARKER_ORIENT_AUTO_START_REVERSE
double sp_offset_distance_to_original(SPOffset *offset, Geom::Point px)
Distance to the original path; that function is called from shape-editor-knotholders to set the radiu...
void sp_offset_top_point(SPOffset const *offset, Geom::Point *px)
Computes a point on the offset; used to set a "seed" position for the control knot.
SVG <pattern> implementation.
Geom::Point sp_star_get_xy(SPStar const *star, SPStarPoint point, gint index, bool randomized)
sp_star_get_xy: Get X-Y value as item coordinate system @star: star item @point: point type to obtain...
TODO: insert short description here.
@ SP_CSS_TEXT_ANCHOR_MIDDLE
@ SP_CSS_TEXT_ANCHOR_START
@ SP_CSS_WRITING_MODE_LR_TB
@ SP_CSS_WRITING_MODE_TB_LR
@ SP_CSS_WRITING_MODE_RL_TB
SPStyle - a style object for SPItem objects.