20#include <glibmm/i18n.h>
81bool SortLabelPlacement(LabelPlacement
const &first, LabelPlacement
const &second)
83 if (first.end.y() == second.end.y()) {
84 return first.end.x() < second.end.x();
86 return first.end.y() < second.end.y();
94 std::sort(placements.begin(), placements.end(), SortLabelPlacement);
106 for (
size_t i = 1; i < placements.size(); i++) {
107 LabelPlacement &place = placements[i];
109 bool changed =
false;
115 for (
size_t j = i; (j > 0) && !
overlaps; --j) {
116 LabelPlacement &otherPlace = placements[j - 1];
118 if (
current.intersects(target)) {
124 place.end = place.start -
desktop->
w2d(normal * place.offset);
129 std::sort(placements.begin(), placements.begin() + i + 1, SortLabelPlacement);
149 double effective = baseAngle +
angle / 2;
154 if (std::abs((where - endPoint).
length()) < scaledFontsize) {
155 where.y() += scaledFontsize * 2;
184 double fontsize, Glib::ustring unit_name,
int maxStrLength,
Geom::Point normal,
bool is_dX =
true)
197 textPos[
Geom::Y] += step * 1.5;
203 bool changed =
false;
206 for (
auto item : placements) {
209 if (boxDelta.intersects(itemBox)) {
236 double angle,
bool to_phantom,
241 double textLen = std::abs((anchor - center).length());
242 double sideLen = std::abs((
end - center).length());
244 double factor = std::min(1.0, textLen / sideLen);
263 double q1 = (ax * ax) + (ay * ay);
264 double q2 = q1 + (ax * bx) + (ay * by);
280 if (!((ax * by - ay * bx < 0.00000000001) && (ax * by - ay * bx > -0.00000000001))) {
281 k2 = (4.0 / 3.0) * (std::sqrt(2 * q1 * q2) - q2) / ((ax * by) - (ay * bx));
285 if (angle > 3.14 || angle < -3.14) {
300 yc + ay + (k2 * ax));
302 yc + by - (k2 * bx));
305 curve->set_name(
"CanvasItemCurve:MeasureToolCurve");
307 curve->lower_to_bottom();
308 curve->set_visible(
true);
310 curve->set_stroke(0x8888887f);
323 pathv *= layer->i2doc_affine().inverse();
324 if (!pathv.
empty()) {
374 return is_start ?
"/tools/measure/measure-start" :
"/tools/measure/measure-end";
404 if (state & GDK_SHIFT_MASK) {
406 auto const unit_name = prefs->getString(
"/tools/measure/unit",
"px");
415 if (state & GDK_CONTROL_MASK) {
417 }
else if (!(state & GDK_SHIFT_MASK)) {
436 if (state & GDK_CONTROL_MASK) {
438 }
else if (!(state & GDK_SHIFT_MASK)) {
471 bool show_hidden = prefs->
getBool(
"/tools/measure/show_hidden",
true);
472 for (
const auto & m : cs[0]) {
479 intersections.push_back(m.ta);
482 intersections.push_back(m.ta);
493 if (event.num_press != 1 || event.button != 1) {
508 snap_manager.unSetup();
518 if (event.keyval == GDK_KEY_Control_L || event.keyval == GDK_KEY_Control_R) {
523 if ((event.
modifiers & GDK_ALT_MASK ) && ((event.keyval == GDK_KEY_c) || (event.keyval == GDK_KEY_C))) {
529 if (event.keyval == GDK_KEY_Control_L || event.keyval == GDK_KEY_Control_R) {
534 if (!(event.
modifiers & GDK_BUTTON1_MASK)) {
535 if (!(event.
modifiers & GDK_SHIFT_MASK)) {
544 snap_manager.preSnap(scp);
545 snap_manager.unSetup();
555 tolerance = prefs->getIntLimited(
"/options/dragtolerance/value", 0, 0, 100);
563 if (event.
modifiers & GDK_CONTROL_MASK) {
565 }
else if (!(event.
modifiers & GDK_SHIFT_MASK)) {
570 auto const sp = snap_manager.freeSnap(scp);
571 end_p = sp.getPoint();
572 snap_manager.unSetup();
583 if (event.button != 1) {
590 if (event.
modifiers & GDK_CONTROL_MASK) {
592 }
else if (!(event.
modifiers & GDK_SHIFT_MASK)) {
597 auto const sp = snap_manager.freeSnap(scp);
598 end_p = sp.getPoint();
599 snap_manager.unSetup();
634 rmarker->
setAttribute(
"id", isStart ?
"Arrow2Sstart" :
"Arrow2Send");
636 rmarker->
setAttribute(
"inkscape:stockid", isStart ?
"Arrow2Sstart" :
"Arrow2Send");
643 marker->updateRepr();
646 rpath->
setAttribute(
"d",
"M 8.72,4.03 L -2.21,0.02 L 8.72,-4.00 C 6.97,-1.63 6.98,1.62 8.72,4.03 z");
647 rpath->
setAttribute(
"id", isStart ?
"Arrow2SstartPath" :
"Arrow2SendPath");
652 Glib::ustring css_str;
656 rpath->
setAttribute(
"transform", isStart ?
"scale(0.3) translate(-2.3,0)" :
"scale(0.3) rotate(180) translate(-2.3,0)");
657 auto path = cast<SPItem>(marker->appendChildRepr(rpath));
680 if(ray.
angle() != 0) {
715 guint32 line_color_primary = 0x0000ff7f;
744 Glib::ustring unit_name = prefs->
getString(
"/tools/measure/unit");
745 if (!unit_name.compare(
"")) {
746 unit_name = DEFAULT_UNIT_NAME;
753 double scale = prefs->
getDouble(
"/tools/measure/scale", 100.0) / 100.0;
755 int precision = prefs->
getInt(
"/tools/measure/precision", 2);
759 double textangle = Geom::rad_from_deg(180) - ray.
angle();
761 textangle = ray.
angle() - Geom::rad_from_deg(180);
794 std::stringstream position;
795 position.imbue(std::locale::classic());
798 guide->
setAttribute(
"inkscape:color",
"rgb(167,0,255)");
801 std::stringstream angle_str;
802 angle_str.imbue(std::locale::classic());
831 svgd =
"m 0.707,0.707 6.586,6.586 m 0,-6.586 -6.586,6.586";
839 if (!pathv.
empty()) {
840 guint32 line_color_secondary = 0xff0000ff;
841 setMeasureItem(pathv,
false,
false, line_color_secondary, measure_repr);
869 std::stringstream font_size;
870 font_size.imbue(std::locale::classic());
891 Glib::ustring css_str;
902 auto text_item = cast<SPText>(layer->appendChildRepr(rtext));
904 text_item->rebuildLayout();
905 text_item->updateRepr();
907 if (!measure_repr && bbox) {
910 pos += Geom::Point::polar(angle+ Geom::rad_from_deg(90), -bbox->height());
921 Glib::ustring css_str;
932 text_item->deleteObject();
933 rgroup->
addChild(rtextitem,
nullptr);
937 auto text_item_box = cast<SPItem>(layer->appendChildRepr(rgroup));
942 text_item_box->transform *=
scale;
945 text_item_box->transform *= layer->i2doc_affine().inverse();
946 text_item_box->updateRepr();
947 text_item_box->doWriteTransform(text_item_box->transform,
nullptr,
true);
949 text_item_box->deleteObject();
950 measure_repr->
addChild(rlabel,
nullptr);
955 text_item->transform *= layer->i2doc_affine().inverse();
956 text_item->doWriteTransform(text_item->transform,
nullptr,
true);
970 bool to_left,
bool to_item,
975 measure += (is_angle ?
"°" : unit_name);
976 if (!
label.empty()) { measure =
label +
": " + measure; }
978 canvas_tooltip->set_fontsize(
fontsize);
979 canvas_tooltip->set_fill(0xffffffff);
980 canvas_tooltip->set_background(background);
988 canvas_tooltip->set_background(0x4444447f);
998 canvas_tooltip->set_visible(
true);
1003 uint32_t color = 0xff0000ff;
1009 canvas_item->lower_to_bottom();
1010 canvas_item->set_pickable(
false);
1011 canvas_item->set_visible(
true);
1030 control_line->set_stroke(color);
1031 control_line->lower_to_bottom();
1032 control_line->set_visible(
true);
1045 canvas_tooltip->set_fontsize(
fontsize);
1046 canvas_tooltip->set_fill(0xffffffff);
1047 canvas_tooltip->set_background(0x00000099);
1049 canvas_tooltip->set_fixed_line(
true);
1050 canvas_tooltip->set_visible(
true);
1071 int precision = prefs->getInt(
"/tools/measure/precision", 2);
1072 bool selected = prefs->getBool(
"/tools/measure/only_selected",
false);
1074 double fontsize = prefs->getDouble(
"/tools/measure/fontsize", 10.0);
1075 double scale = prefs->getDouble(
"/tools/measure/scale", 100.0) / 100.0;
1076 Glib::ustring unit_name = prefs->getString(
"/tools/measure/unit", unit->abbr);
1080 if (newover !=
over) {
1088 if (
auto bbox =
over->
bounds(box_type, affine)) {
1089 item_width = Quantity::convert(bbox->width(),
"px", unit_name);
1090 item_height = Quantity::convert(bbox->height(),
"px", unit_name);
1091 item_x = Quantity::convert(bbox->left(),
"px", unit_name);
1092 item_y = Quantity::convert(bbox->top(),
"px", unit_name);
1094 if (
auto shape = cast<SPShape>(
over)) {
1095 auto pw = paths_to_pw(shape->curve()->get_pathvector());
1101 gchar *measure_str =
nullptr;
1102 std::stringstream precision_str;
1103 precision_str.imbue(std::locale::classic());
1104 double origin = Quantity::convert(14,
"px", unit->abbr);
1105 double yaxis_shift = Quantity::convert(
fontsize,
"px", unit->abbr);
1109 double gap = Quantity::convert(7 +
fontsize,
"px", unit->abbr);
1117 if (is<SPShape>(
over)) {
1119 precision_str << _(
"Length") <<
": %." << precision <<
"f %s";
1120 measure_str = g_strdup_printf(precision_str.str().c_str(),
item_length, unit_name.c_str());
1121 precision_str.str(
"");
1125 }
else if (is<SPGroup>(
over)) {
1127 measure_str = _(
"Press 'CTRL' to measure into group");
1133 precision_str <<
"Y: %." << precision <<
"f %s";
1134 measure_str = g_strdup_printf(precision_str.str().c_str(),
item_y, unit_name.c_str());
1135 precision_str.str(
"");
1139 precision_str <<
"X: %." << precision <<
"f %s";
1140 measure_str = g_strdup_printf(precision_str.str().c_str(),
item_x, unit_name.c_str());
1141 precision_str.str(
"");
1145 precision_str << _(
"Height") <<
": %." << precision <<
"f %s";
1146 measure_str = g_strdup_printf(precision_str.str().c_str(),
item_height, unit_name.c_str());
1147 precision_str.str(
"");
1151 precision_str << _(
"Width") <<
": %." << precision <<
"f %s";
1152 measure_str = g_strdup_printf(precision_str.str().c_str(),
item_width, unit_name.c_str());
1153 precision_str.str(
"");
1155 g_free(measure_str);
1185 bool show_in_between = prefs->getBool(
"/tools/measure/show_in_between",
true);
1186 bool all_layers = prefs->getBool(
"/tools/measure/all_layers",
true);
1192 p.
start(start_p_doc);
1197 double baseAngle = 0;
1207 if (angle < -M_PI) {
1212 std::vector<SPItem*>
items;
1218 std::vector<double> intersection_times;
1219 bool only_selected = prefs->getBool(
"/tools/measure/only_selected",
false);
1220 for (
auto i :
items) {
1226 if (
auto e = cast<SPGenericEllipse>(
item)) {
1231 }
else if (
auto shape = cast<SPShape>(
item)) {
1234 if (is<SPText>(
item) || is<SPFlowtext>(
item)) {
1239 if (iter == iter_next) {
1246 if (
curve.is_empty()) {
1259 Glib::ustring unit_name = prefs->getString(
"/tools/measure/unit");
1260 if (!unit_name.compare(
"")) {
1261 unit_name = DEFAULT_UNIT_NAME;
1263 double scale = prefs->getDouble(
"/tools/measure/scale", 100.0) / 100.0;
1264 double fontsize = prefs->getDouble(
"/tools/measure/fontsize", 10.0);
1269 std::vector<Geom::Point> intersections;
1270 std::sort(intersection_times.begin(), intersection_times.end());
1271 for (
double & intersection_time : intersection_times) {
1272 intersections.push_back(lineseg[0].pointAt(intersection_time));
1275 if(!show_in_between && intersection_times.size() > 1) {
1278 intersections.clear();
1279 intersections.push_back(
start);
1280 intersections.push_back(
end);
1282 if (!prefs->getBool(
"/tools/measure/ignore_1st_and_last",
true)) {
1283 intersections.insert(intersections.begin(),lineseg[0].
pointAt(0));
1284 intersections.push_back(lineseg[0].pointAt(1));
1286 int precision = prefs->getInt(
"/tools/measure/precision", 2);
1287 Glib::ustring MTSpath = prefs->getString(
"/tools/measure/MTSpath",
"");
1288 bool showDeltas =
false;
1289 bool show_deltas_label =
false;
1290 bool show_segments_label =
false;
1291 double seg_min_len = 0.1;
1292 bool showAngle =
true;
1293 if (!MTSpath.empty()){
1294 Glib::ustring pathStr = MTSpath;
1295 pathStr.append(
"/segments_min_length");
1296 seg_min_len = prefs->getDouble(pathStr.c_str(), 0.1);
1298 pathStr.append(
"/show_segments_label");
1299 show_segments_label = prefs->getBool(pathStr.c_str(),
false);
1301 pathStr.append(
"/show_deltas_label");
1302 show_deltas_label = prefs->getBool(pathStr.c_str(),
false);
1304 pathStr.append(
"/show_deltas");
1305 showDeltas = prefs->getBool(pathStr.c_str(),
false);
1307 pathStr.append(
"/show_angle");
1308 showAngle = prefs->getBool(pathStr.c_str(),
true);
1312 std::vector<LabelPlacement> placements;
1313 for (
size_t idx = 1; idx < intersections.size(); ++idx) {
1314 LabelPlacement placement;
1315 placement.lengthVal = (intersections[idx] - intersections[idx - 1]).length();
1318 placement.start =
_desktop->
doc2dt((intersections[idx - 1] + intersections[idx]) / 2);
1319 placement.end = placement.start - (normal * placement.offset);
1320 if (placement.lengthVal > seg_min_len) {
1324 placements.push_back(placement);
1330 repositionOverlappingLabels(placements,
_desktop, windowNormal,
fontsize, precision);
1333 Geom::Point dXmidpos, dYmidpos, dXTextPos, dYTextPos;
1334 bool dX_is0, dY_is0;
1341 if (!dX_is0 && !dY_is0) {
1343 deltasBasePoint = basePointinfo[0];
1344 dXmidpos = basePointinfo[3];
1345 dYmidpos = basePointinfo[4];
1346 std::vector<LabelPlacement> allPlacements = placements;
1347 if (placements.size() > 1) {
1348 LabelPlacement placement;
1350 (intersections[intersections.size() - 1] + normal *
dimension_offset)).length();
1354 (intersections[intersections.size() - 1] + normal *
dimension_offset)) / 2);
1355 placement.end = placement.start;
1356 allPlacements.push_back(placement);
1358 const int intdXdY =
static_cast<int>(std::ceil(dX * dY / 2));
1359 int maxStrLength = (show_segments_label ? 3 : 0) + std::to_string(intdXdY).length() + precision + unit_name.length();
1360 dXTextPos = calcDeltaLabelTextPos(allPlacements,
_desktop, dXmidpos,
fontsize, unit_name, maxStrLength, basePointinfo[1],
true);
1361 dYTextPos = calcDeltaLabelTextPos(allPlacements,
_desktop, dYmidpos,
fontsize, unit_name, maxStrLength, basePointinfo[2],
false);
1364 double dYscaled = dY *
scale;
1365 int dYstrLen = std::to_string(dYscaled).length();
1366 if (show_deltas_label) { dYstrLen += 3; }
1381 for (
auto & place : placements) {
1383 false, to_item, to_phantom, measure_repr, (show_segments_label ? place.label :
""));
1388 false, to_item, to_phantom, measure_repr);
1400 true, to_item, to_phantom, measure_repr);
1405 if (placements.size() > 1) {
1406 double totallengthval = (intersections[intersections.size()-1] - intersections[0]).length();
1410 false, to_item, to_phantom, measure_repr);
1421 for (
size_t idx = 0; idx < intersections.size(); ++idx) {
1424 gchar *cross_number;
1425 if (!prefs->getBool(
"/tools/measure/ignore_1st_and_last",
true)) {
1426 cross_number= g_strdup_printf(_(
"Crossing %lu"),
static_cast<unsigned long>(idx));
1428 cross_number= g_strdup_printf(_(
"Crossing %lu"),
static_cast<unsigned long>(idx + 1));
1430 if (!prefs->getBool(
"/tools/measure/ignore_1st_and_last",
true) && idx == 0) {
1435 g_free(cross_number);
1457 if ((showDeltas) && (!dX_is0) && (!dY_is0)) {
1464 if (placements.size() > 1) {
1473 for (
auto & place : placements) {
1507 std::stringstream stroke_width;
1508 stroke_width.imbue(std::locale::classic());
1512 stroke_width << strokewidth;
1517 char const * stroke_linecap = is_curve ?
"butt" :
"square";
1531 Glib::ustring css_str;
1537 measure_repr->
addChild(repr,
nullptr);
1540 auto item = cast<SPItem>(layer->appendChildRepr(repr));
1565 int precision = prefs->
getInt(
"/tools/measure/precision", 2);
1566 Glib::ustring unit_name = prefs->
getString(
"/tools/measure/unit");
1567 Glib::ustring MTSpath = prefs->
getString(
"/tools/measure/MTSpath",
"");
1568 Glib::ustring pathStr = MTSpath;
1569 pathStr.append(
"/show_angle");
1570 bool showAngleOpt = prefs->
getBool(pathStr.c_str(),
true);
1572 pathStr.append(
"/show_deltas");
1573 bool deltasOpt = prefs->
getBool(pathStr.c_str(),
true);
1575 pathStr.append(
"/labels");
1576 bool labelsOpt = prefs->
getBool(pathStr.c_str(),
true);
1578 pathStr.append(
"/units");
1579 bool unitsOpt = prefs->
getBool(pathStr.c_str(),
true);
1581 pathStr.append(
"/tabs");
1582 bool tabsOpt = prefs->
getBool(pathStr.c_str(),
true);
1584 pathStr.append(
"/length");
1585 bool lengthOpt = prefs->
getBool(pathStr.c_str(),
true);
1587 pathStr.append(
"/between");
1588 bool betweenOpt = prefs->
getBool(pathStr.c_str(),
true);
1590 pathStr.append(
"/angle");
1591 bool angleOpt = prefs->
getBool(pathStr.c_str(),
true);
1593 pathStr.append(
"/dX");
1594 bool dXOpt = prefs->
getBool(pathStr.c_str(),
true);
1596 pathStr.append(
"/dY");
1597 bool dYOpt = prefs->
getBool(pathStr.c_str(),
true);
1599 pathStr.append(
"/segments");
1600 bool segmentsOpt = prefs->
getBool(pathStr.c_str(),
true);
1602 pathStr.append(
"/shape_width");
1603 bool shape_widthOpt = prefs->
getBool(pathStr.c_str(),
true);
1605 pathStr.append(
"/shape_height");
1606 bool shape_heightOpt = prefs->
getBool(pathStr.c_str(),
true);
1608 pathStr.append(
"/shape_X");
1609 bool shape_XOpt = prefs->
getBool(pathStr.c_str(),
true);
1611 pathStr.append(
"/shape_Y");
1612 bool shape_YOpt = prefs->
getBool(pathStr.c_str(),
true);
1614 pathStr.append(
"/shape_length");
1615 bool shape_lengthOpt = prefs->
getBool(pathStr.c_str(),
true);
1617 Glib::ustring stringToCopy =
"";
1644 stringToCopy += _(
"\nIntersection segments lengths:\n");
1645 Glib::ustring sep = tabsOpt ?
"\t" :
" ";
1647 if (labelsOpt) { stringToCopy +=
key +
":" + sep; }
1648 stringToCopy += Glib::ustring::format(std::setprecision(precision), std::fixed, value);
1649 if (unitsOpt) { stringToCopy += sep + unit_name; }
1650 stringToCopy +=
"\n";
1655 bool showTitle =
true;
1656 const char* title = _(
"\nInfo about the shape under the pointer:\n");
1659 stringToCopy += title;
1666 stringToCopy += title;
1673 stringToCopy += title;
1680 stringToCopy += title;
1687 stringToCopy += title;
1718 double midX = (std::abs(dX) / 2);
1719 double midY = (std::abs(dY) / 2);
1720 if ((dX > 0) && (dY > 0)) {
1727 if ((dX > 0) && (dY < 0)) {
1734 if ((dX < 0) && (dY > 0)) {
1741 if ((dX < 0) && (dY < 0)) {
1748 std::vector<Geom::Point>
result;
1749 result.push_back(deltasBasePoint);
1750 result.push_back(dXnormal);
1751 result.push_back(dYnormal);
1752 result.push_back(dXbase);
1753 result.push_back(dYbase);
1768 if (positiveAllowed) {
1769 if ((value <= reference_value + epsilon) && (value >= reference_value)) {
return true; }
1771 if (negativeAllowed) {
1772 if ((value >= reference_value - epsilon) && (value <= reference_value)) {
return true; }
1789 Glib::ustring value = Glib::ustring::format(std::setprecision(precision), std::fixed, lengths[
id]);
1790 Glib::ustring sep = tabSeparated ?
"\t" :
" ";
1791 Glib::ustring
result = withLabel ? labels[id] +
":" + sep :
"";
3x3 matrix representing an affine transformation.
Coord expansionX() const
Calculates the amount of x-scaling imparted by the Affine.
Affine inverse() const
Compute the inverse matrix.
Bezier curve with compile-time specified order.
CPoint clamp(CPoint const &p) const
Clamp point to the rectangle.
void expandBy(C amount)
Expand the rectangle in both directions by the specified amount.
Axis-aligned rectangle that can be empty.
void push_back(Path const &path)
Append a path at the end.
Point pointAt(Coord t) const
bool empty() const
Check whether the vector contains any paths.
Sequence of contiguous curves, aka spline.
void appendNew(Args &&... args)
Append a new curve to the path.
void start(Point const &p)
Two-dimensional point that doubles as a vector.
bool isFinite() const
Check whether both coordinates are finite.
Straight ray from a specific point to infinity.
void setPoints(Point const &a, Point const &b)
Axis aligned, non-empty rectangle.
bool interiorContains(Point const &p) const
Check whether the interior includes the given point.
Rotation around the origin.
Translate inverse() const
Get the inverse translation.
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
SPObject * layerForObject(SPObject *object)
Return layer that contains object.
SPGroup * currentLayer() const
Returns current top layer.
MessageId flash(MessageType type, char const *message)
Temporarily pushes a message onto the stack.
void clear()
Unselects all selected objects.
Geom::Affine getSelectedPageAffine() const
Preference storage class.
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
double getDouble(Glib::ustring const &pref_path, double def=0.0, Glib::ustring const &unit="")
Retrieve a floating point value.
Glib::ustring getString(Glib::ustring const &pref_path, Glib::ustring const &def="")
Retrieve an UTF-8 string.
static Preferences * get()
Access the singleton Preferences object.
int getInt(Glib::ustring const &pref_path, int def=0)
Retrieve an integer.
Geom::Point getPoint(Glib::ustring const &pref_path, Geom::Point def=Geom::Point())
Retrieve a point.
void setPoint(Glib::ustring const &pref_path, Geom::Point value)
Set a point value.
void add(XML::Node *repr)
Add an XML node's SPObject to the set of selected objects.
bool includes(XML::Node *repr, bool anyAncestor=false)
Returns true if the given item is selected.
Class to store data for points which are snap candidates, either as a source or as a target.
void addOrigin(Geom::Point pt)
Class describing the result of an attempt to snap.
Geom::Point getPoint() const
Holds a position within the glyph output of Layout.
SPCurve convertToCurves(iterator const &from_glyph, iterator const &to_glyph) const
Convert the specified range of characters into their bezier outlines.
iterator begin() const
Returns an iterator pointing at the first glyph of the flowed output.
System-wide clipboard manager.
static ClipboardManager * get()
virtual bool copyString(Glib::ustring str)=0
static void showDialog(SPDesktop *desktop, SPKnot *knot, Glib::ustring const &unit_name)
double value(Unit const *u) const
Return the quantity's value in the specified unit.
static double convert(double from_dist, Unit const *from, Unit const *to)
Convert distances.
Interface for refcounted XML nodes.
virtual void addChild(Node *child, Node *after)=0
Insert another node as a child of this node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
bool setAttributeSvgDouble(Util::const_char_ptr key, double val)
For attributes where an exponent is allowed.
Wrapper around a Geom::PathVector object.
To do: update description of desktop.
Inkscape::UI::Widget::Canvas * getCanvas() const
double current_zoom() const
SPDocument * getDocument() const
Inkscape::MessageStack * messageStack() const
Inkscape::CanvasItemGroup * getCanvasTemp() const
Geom::Affine const & dt2doc() const
Geom::Affine const & d2w() const
Transformation from desktop to window coordinates.
SPItem * getItemAtPoint(Geom::Point const &p, bool into_groups, SPItem *upto=nullptr) const
SPNamedView * getNamedView() const
Inkscape::Selection * getSelection() const
bool is_yaxisdown() const
Inkscape::LayerManager & layerManager()
Geom::Affine const & doc2dt() const
Geom::Affine const & w2d() const
Transformation from window to desktop coordinates (zoom/rotate).
Typed SVG document implementation.
bool get_origin_follows_page()
SPRoot * getRoot()
Returns our SPRoot.
SPObject * getObjectById(std::string const &id) const
std::vector< SPItem * > getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool take_hidden=false, bool take_insensitive=false, bool take_groups=true, bool enter_groups=false, bool enter_layers=true) const
Get items whose bounding box overlaps with given area.
Inkscape::PageManager & getPageManager()
SPDefs * getDefs()
Return the main defs object for the document.
Inkscape::XML::Document * getReprDoc()
Our Inkscape::XML::Document.
int ensureUpToDate(unsigned int object_modified_tag=0)
Repeatedly works on getting the document updated, since sometimes it takes more than one pass to get ...
Inkscape::Util::Quantity getHeight() const
Base class for visual SVG elements.
Geom::Affine i2dt_affine() const
Returns the transformation from item to desktop coords.
Geom::OptRect bounds(BBoxType type, Geom::Affine const &transform=Geom::identity()) const
Geom::Affine i2doc_affine() const
Returns the accumulated transformation of the item and all its ancestors, including root's viewport.
Desktop-bound visual control object.
sigc::signal< void(SPKnot *, unsigned int)> ungrabbed_signal
sigc::signal< void(SPKnot *, Geom::Point const &, unsigned int)> moved_signal
sigc::signal< void(SPKnot *, unsigned int)> click_signal
static void unref(SPKnot *knot)
void hide()
Hide knot on its canvas.
void show()
Show knot on its canvas.
void updateCtrl()
Update knot's control state.
Geom::Point position() const
Returns position of knot.
void moveto(Geom::Point const &p)
Move knot to new position, without emitting a MOVED signal.
Inkscape::Util::Unit const * getDisplayUnit() const
Returns namedview's default unit.
SPObject is an abstract base class of all of the document nodes at the SVG document level.
void appendChild(Inkscape::XML::Node *child)
Inkscape::XML::Node * updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT)
Updates the object's repr based on the object's state.
SPObject * appendChildRepr(Inkscape::XML::Node *repr)
Append repr as child of this object.
Class to coordinate snapping operations.
void setup(SPDesktop const *desktop, bool snapindicator=true, SPObject const *item_to_ignore=nullptr, std::vector< Inkscape::SnapCandidatePoint > *unselected_nodes=nullptr)
Convenience shortcut when there is only one item to ignore.
Inkscape::SnappedPoint freeSnap(Inkscape::SnapCandidatePoint const &p, Geom::OptRect const &bbox_to_snap=Geom::OptRect(), bool to_path_only=false) const
Try to snap a point to grids, guides or objects.
System-wide clipboard management - class declaration.
std::shared_ptr< Css const > css
void sp_desktop_apply_style_tool(SPDesktop *desktop, Inkscape::XML::Node *repr, Glib::ustring const &tool_path, bool with_text)
Apply the desktop's current style or the tool style to repr.
Editable view implementation.
static char const *const current
TODO: insert short description here.
static bool overlaps(Geom::Rect const &area, Geom::Rect const &box)
constexpr Coord infinity()
Get a value representing infinity.
double Coord
Floating point type used to store coordinates.
Geom::PathVector pathv_to_linear_and_cubic_beziers(Geom::PathVector const &pathv)
Specific geometry functions for Inkscape, not provided my lib2geom.
Macro for icon names used in Inkscape.
Declarations for SPKnot: Desktop-bound visual control object.
void normal(std::vector< Point > &N, std::vector< Point > const &B)
double angle(std::vector< Point > const &A)
Coord length(LineSegment const &seg)
Affine identity()
Create an identity matrix.
Crossings crossings(Curve const &a, Curve const &b)
std::vector< Crossings > CrossingSet
void delete_duplicates(Crossings &crs)
Point unit_vector(Point const &a)
D2< T > rot90(D2< T > const &a)
Coord LInfty(Point const &p)
Point middle_point(LineSegment const &_segment)
std::string rgba_to_hex(uint32_t value, bool alpha)
Output the RGBA value as a #RRGGBB hex color, if alpha is true then the output will be #RRGGBBAA inst...
static R & release(R &r)
Decrements the reference count of a anchored object.
Glib::ustring format_classic(T const &... args)
void inspect_event(E &&event, Fs... funcs)
Perform pattern-matching on a CanvasEvent.
@ SNAPSOURCE_OTHER_HANDLE
@ CANVAS_ITEM_CTRL_TYPE_POINT
@ CANVAS_ITEM_CTRL_TYPE_MARKER
static cairo_user_data_key_t key
SPCSSAttr * sp_repr_css_attr_new()
Creates an empty SPCSSAttr (a class for manipulating CSS style properties).
void sp_repr_css_write_string(SPCSSAttr *css, Glib::ustring &str)
Write a style attribute string from a list of properties stored in an SPCSAttr object.
void sp_repr_css_set_property_double(SPCSSAttr *css, gchar const *name, double value)
Set a style property to a new float value (e.g.
void sp_repr_css_attr_unref(SPCSSAttr *css)
Unreferences an SPCSSAttr (will be garbage collected if no references remain).
void sp_repr_css_set_property_string(SPCSSAttr *css, char const *name, std::string const &value)
Set a style property to a standard string.
void sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value)
Set a style property to a new value (e.g.
TODO: insert short description here.
SPRoot: SVG <svg> implementation.
Abstract base class for events.
unsigned modifiers
The modifiers mask immediately before the event.
Movement of the mouse pointer.
Interface for XML documents.
virtual Node * createTextNode(char const *content)=0
virtual Node * createElement(char const *name)=0
Geom::PathVector sp_svg_read_pathv(char const *str)
static void sp_svg_write_path(Inkscape::SVG::PathString &str, Geom::Path const &p, bool normalize=false)
Inkscape::Text::Layout const * te_get_layout(SPItem const *item)