summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-04-09 18:54:52 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-04-09 18:54:52 +0000
commit42569eeea6a78406c723a0c2139a6adbb5f9c9cc (patch)
tree480aff49241ce0c5b30837bf8bd6137e0a9f2789
parentupdate to trunk (diff)
parentCleaned up cmake files to build successfully on Linux. (diff)
downloadinkscape-42569eeea6a78406c723a0c2139a6adbb5f9c9cc.tar.gz
inkscape-42569eeea6a78406c723a0c2139a6adbb5f9c9cc.zip
update to trunk
(bzr r12588.1.40)
-rwxr-xr-xpackaging/scripts/lp-mark-bugs-released6
-rw-r--r--po/lv.po762
-rwxr-xr-xshare/extensions/restack.py8
-rwxr-xr-xshare/extensions/text_extract.py24
-rw-r--r--share/extensions/text_merge.py4
-rw-r--r--share/keys/macromedia-freehand-mx.xml4
-rw-r--r--src/2geom/line.h17
-rw-r--r--src/CMakeLists.txt44
-rw-r--r--src/document.cpp11
-rw-r--r--src/document.h1
-rw-r--r--src/helper/CMakeLists.txt2
-rw-r--r--src/helper/Makefile_insert2
-rw-r--r--src/helper/geom-pathstroke.cpp770
-rw-r--r--src/helper/geom-pathstroke.h58
-rw-r--r--src/inkgc/CMakeLists.txt5
-rw-r--r--src/livarot/ShapeMisc.cpp8
-rw-r--r--src/live_effects/CMakeLists.txt51
-rw-r--r--src/live_effects/Makefile_insert2
-rw-r--r--src/live_effects/lpe-bspline.cpp50
-rw-r--r--src/live_effects/lpe-bspline.h3
-rw-r--r--src/live_effects/lpe-jointype.cpp129
-rw-r--r--src/live_effects/lpe-jointype.h5
-rw-r--r--src/live_effects/lpe-perspective-envelope.cpp12
-rw-r--r--src/live_effects/lpe-powerstroke.cpp33
-rw-r--r--src/live_effects/lpe-taperstroke.cpp204
-rw-r--r--src/live_effects/pathoutlineprovider.cpp803
-rw-r--r--src/live_effects/pathoutlineprovider.h55
-rw-r--r--src/svg-profile.h2
-rw-r--r--src/trace/potrace/auxiliary.h31
-rw-r--r--src/trace/potrace/bitmap.h33
-rw-r--r--src/trace/potrace/bitops.h83
-rw-r--r--src/trace/potrace/curve.cpp26
-rw-r--r--src/trace/potrace/curve.h2
-rw-r--r--src/trace/potrace/decompose.cpp29
-rw-r--r--src/trace/potrace/decompose.h2
-rw-r--r--src/trace/potrace/greymap.cpp61
-rw-r--r--src/trace/potrace/greymap.h5
-rw-r--r--src/trace/potrace/lists.h2
-rw-r--r--src/trace/potrace/potracelib.cpp2
-rw-r--r--src/trace/potrace/potracelib.h2
-rw-r--r--src/trace/potrace/progress.h2
-rw-r--r--src/trace/potrace/render.cpp4
-rw-r--r--src/trace/potrace/render.h2
-rw-r--r--src/trace/potrace/trace.cpp66
-rw-r--r--src/trace/potrace/trace.h2
-rw-r--r--src/ui/CMakeLists.txt29
-rw-r--r--src/ui/dialog/filter-effects-dialog.cpp2
-rw-r--r--src/ui/tool/curve-drag-point.cpp4
-rw-r--r--src/ui/tool/multi-path-manipulator.h2
-rw-r--r--src/ui/tool/node.cpp15
-rw-r--r--src/ui/tool/path-manipulator.cpp44
-rw-r--r--src/ui/tool/path-manipulator.h2
-rw-r--r--src/ui/tools/box3d-tool.h2
-rw-r--r--src/ui/tools/connector-tool.cpp2
-rw-r--r--src/ui/tools/dynamic-base.h2
-rw-r--r--src/ui/tools/gradient-tool.cpp2
-rw-r--r--src/ui/tools/node-tool.cpp2
-rw-r--r--src/ui/tools/pen-tool.cpp4
-rw-r--r--src/ui/tools/spray-tool.cpp2
-rw-r--r--src/ui/widget/page-sizer.cpp169
-rw-r--r--src/ui/widget/page-sizer.h21
-rw-r--r--src/uri-references.cpp2
62 files changed, 2020 insertions, 1715 deletions
diff --git a/packaging/scripts/lp-mark-bugs-released b/packaging/scripts/lp-mark-bugs-released
index f18f1468a..7e936213d 100755
--- a/packaging/scripts/lp-mark-bugs-released
+++ b/packaging/scripts/lp-mark-bugs-released
@@ -21,7 +21,7 @@ import tempfile
from launchpadlib.launchpad import Launchpad
from launchpadlib.errors import HTTPError
-opt_dry_run = True
+opt_dry_run = False
def mark_released (bug):
if bug.status == 'Fix Committed':
@@ -68,7 +68,9 @@ def main():
mark_released(task)
except HTTPError, error:
- print 'An error happened in the upload:', error.content
+ print 'An error happened in the upload: %s\n%s' %(
+ error.content,
+ error.__dict__)
sys.exit(1)
if __name__ == '__main__':
diff --git a/po/lv.po b/po/lv.po
index 1d15f8461..8d6e1e11c 100644
--- a/po/lv.po
+++ b/po/lv.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Inkscape\n"
"Report-Msgid-Bugs-To: inkscape-devel@lists.sourceforge.net\n"
-"POT-Creation-Date: 2015-02-27 20:13+0100\n"
-"PO-Revision-Date: 2015-03-01 17:37+0200\n"
+"POT-Creation-Date: 2015-03-10 09:10+0100\n"
+"PO-Revision-Date: 2015-03-22 14:04+0200\n"
"Last-Translator: Jānis Eisaks <je@dv.lv>\n"
"Language-Team: Latvian <lata-l10n@googlegroups.com>\n"
"Language: lv\n"
@@ -936,17 +936,17 @@ msgstr "Melna gaisma"
#: ../share/filters/filters.svg.h:411 ../share/filters/filters.svg.h:575 ../share/filters/filters.svg.h:587 ../share/filters/filters.svg.h:627 ../share/filters/filters.svg.h:631 ../share/filters/filters.svg.h:819
#: ../share/filters/filters.svg.h:827 ../share/filters/filters.svg.h:831 ../src/extension/internal/bitmap/colorize.cpp:52 ../src/extension/internal/filter/bumps.h:101 ../src/extension/internal/filter/bumps.h:321
-#: ../src/extension/internal/filter/bumps.h:328 ../src/extension/internal/filter/color.h:82 ../src/extension/internal/filter/color.h:164 ../src/extension/internal/filter/color.h:171 ../src/extension/internal/filter/color.h:262
-#: ../src/extension/internal/filter/color.h:340 ../src/extension/internal/filter/color.h:347 ../src/extension/internal/filter/color.h:437 ../src/extension/internal/filter/color.h:532 ../src/extension/internal/filter/color.h:654
-#: ../src/extension/internal/filter/color.h:751 ../src/extension/internal/filter/color.h:830 ../src/extension/internal/filter/color.h:921 ../src/extension/internal/filter/color.h:1049 ../src/extension/internal/filter/color.h:1119
-#: ../src/extension/internal/filter/color.h:1212 ../src/extension/internal/filter/color.h:1324 ../src/extension/internal/filter/color.h:1429 ../src/extension/internal/filter/color.h:1505 ../src/extension/internal/filter/color.h:1609
-#: ../src/extension/internal/filter/color.h:1616 ../src/extension/internal/filter/morphology.h:194 ../src/extension/internal/filter/overlays.h:73 ../src/extension/internal/filter/paint.h:99 ../src/extension/internal/filter/paint.h:713
-#: ../src/extension/internal/filter/paint.h:717 ../src/extension/internal/filter/shadows.h:73 ../src/extension/internal/filter/transparency.h:345 ../src/filter-enums.cpp:67 ../src/ui/dialog/clonetiler.cpp:830
-#: ../src/ui/dialog/clonetiler.cpp:981 ../src/ui/dialog/document-properties.cpp:164 ../share/extensions/color_HSL_adjust.inx.h:20 ../share/extensions/color_blackandwhite.inx.h:3 ../share/extensions/color_brighter.inx.h:2
-#: ../share/extensions/color_custom.inx.h:15 ../share/extensions/color_darker.inx.h:2 ../share/extensions/color_desaturate.inx.h:2 ../share/extensions/color_grayscale.inx.h:2 ../share/extensions/color_lesshue.inx.h:2
-#: ../share/extensions/color_lesslight.inx.h:2 ../share/extensions/color_lesssaturation.inx.h:2 ../share/extensions/color_morehue.inx.h:2 ../share/extensions/color_morelight.inx.h:2 ../share/extensions/color_moresaturation.inx.h:2
-#: ../share/extensions/color_negative.inx.h:2 ../share/extensions/color_randomize.inx.h:8 ../share/extensions/color_removeblue.inx.h:2 ../share/extensions/color_removegreen.inx.h:2 ../share/extensions/color_removered.inx.h:2
-#: ../share/extensions/color_replace.inx.h:6 ../share/extensions/color_rgbbarrel.inx.h:2 ../share/extensions/interp_att_g.inx.h:19
+#: ../src/extension/internal/filter/bumps.h:328 ../src/extension/internal/filter/color.h:83 ../src/extension/internal/filter/color.h:165 ../src/extension/internal/filter/color.h:172 ../src/extension/internal/filter/color.h:283
+#: ../src/extension/internal/filter/color.h:337 ../src/extension/internal/filter/color.h:415 ../src/extension/internal/filter/color.h:422 ../src/extension/internal/filter/color.h:512 ../src/extension/internal/filter/color.h:607
+#: ../src/extension/internal/filter/color.h:729 ../src/extension/internal/filter/color.h:826 ../src/extension/internal/filter/color.h:905 ../src/extension/internal/filter/color.h:996 ../src/extension/internal/filter/color.h:1124
+#: ../src/extension/internal/filter/color.h:1194 ../src/extension/internal/filter/color.h:1287 ../src/extension/internal/filter/color.h:1399 ../src/extension/internal/filter/color.h:1504 ../src/extension/internal/filter/color.h:1580
+#: ../src/extension/internal/filter/color.h:1684 ../src/extension/internal/filter/color.h:1691 ../src/extension/internal/filter/morphology.h:194 ../src/extension/internal/filter/overlays.h:73 ../src/extension/internal/filter/paint.h:99
+#: ../src/extension/internal/filter/paint.h:713 ../src/extension/internal/filter/paint.h:717 ../src/extension/internal/filter/shadows.h:73 ../src/extension/internal/filter/transparency.h:345 ../src/filter-enums.cpp:67
+#: ../src/ui/dialog/clonetiler.cpp:830 ../src/ui/dialog/clonetiler.cpp:981 ../src/ui/dialog/document-properties.cpp:164 ../share/extensions/color_HSL_adjust.inx.h:20 ../share/extensions/color_blackandwhite.inx.h:3
+#: ../share/extensions/color_brighter.inx.h:2 ../share/extensions/color_custom.inx.h:15 ../share/extensions/color_darker.inx.h:2 ../share/extensions/color_desaturate.inx.h:2 ../share/extensions/color_grayscale.inx.h:2
+#: ../share/extensions/color_lesshue.inx.h:2 ../share/extensions/color_lesslight.inx.h:2 ../share/extensions/color_lesssaturation.inx.h:2 ../share/extensions/color_morehue.inx.h:2 ../share/extensions/color_morelight.inx.h:2
+#: ../share/extensions/color_moresaturation.inx.h:2 ../share/extensions/color_negative.inx.h:2 ../share/extensions/color_randomize.inx.h:8 ../share/extensions/color_removeblue.inx.h:2 ../share/extensions/color_removegreen.inx.h:2
+#: ../share/extensions/color_removered.inx.h:2 ../share/extensions/color_replace.inx.h:6 ../share/extensions/color_rgbbarrel.inx.h:2 ../share/extensions/interp_att_g.inx.h:19
msgid "Color"
msgstr "Krāsa"
@@ -4815,7 +4815,7 @@ msgid "Add Noise"
msgstr "Pievienot troksni"
#. _settings->add_checkbutton(false, SP_ATTR_STITCHTILES, _("Stitch Tiles"), "stitch", "noStitch");
-#: ../src/extension/internal/bitmap/addNoise.cpp:47 ../src/extension/internal/filter/color.h:426 ../src/extension/internal/filter/color.h:1497 ../src/extension/internal/filter/color.h:1585 ../src/extension/internal/filter/distort.h:69
+#: ../src/extension/internal/bitmap/addNoise.cpp:47 ../src/extension/internal/filter/color.h:501 ../src/extension/internal/filter/color.h:1572 ../src/extension/internal/filter/color.h:1660 ../src/extension/internal/filter/distort.h:69
#: ../src/extension/internal/filter/morphology.h:60 ../src/rdf.cpp:244 ../src/ui/dialog/filter-effects-dialog.cpp:2842 ../src/ui/dialog/filter-effects-dialog.cpp:2916 ../src/ui/dialog/object-attributes.cpp:49
#: ../share/extensions/jessyInk_effects.inx.h:5 ../share/extensions/jessyInk_export.inx.h:3 ../share/extensions/jessyInk_transitions.inx.h:5 ../share/extensions/webslicer_create_rect.inx.h:14
msgid "Type:"
@@ -4923,7 +4923,7 @@ msgstr "Kokogle"
msgid "Apply charcoal stylization to selected bitmap(s)"
msgstr "Alfa -> iezīmētai"
-#: ../src/extension/internal/bitmap/colorize.cpp:50 ../src/extension/internal/filter/color.h:317
+#: ../src/extension/internal/bitmap/colorize.cpp:50 ../src/extension/internal/filter/color.h:392
msgid "Colorize"
msgstr "Tonēšana"
@@ -4931,7 +4931,7 @@ msgstr "Tonēšana"
msgid "Colorize selected bitmap(s) with specified color, using given opacity"
msgstr "Krāsot atlasīto(-ās) bitkarti(-es) ar norādīto krāsu, izmantojot doto necauspīdīgumu"
-#: ../src/extension/internal/bitmap/contrast.cpp:40 ../src/extension/internal/filter/color.h:1114
+#: ../src/extension/internal/bitmap/contrast.cpp:40 ../src/extension/internal/filter/color.h:1189
msgid "Contrast"
msgstr "Kontrasts"
@@ -5039,7 +5039,7 @@ msgstr "Implozija"
msgid "Implode selected bitmap(s)"
msgstr "Implodēt atlasīto(-ās) bitkarti(-es)"
-#: ../src/extension/internal/bitmap/level.cpp:41 ../src/extension/internal/filter/color.h:742 ../src/extension/internal/filter/image.h:56 ../src/extension/internal/filter/morphology.h:66 ../src/extension/internal/filter/paint.h:345
+#: ../src/extension/internal/bitmap/level.cpp:41 ../src/extension/internal/filter/color.h:817 ../src/extension/internal/filter/image.h:56 ../src/extension/internal/filter/morphology.h:66 ../src/extension/internal/filter/paint.h:345
msgid "Level"
msgstr "Līmenis"
@@ -5063,7 +5063,7 @@ msgstr "Līmeņojiet atlasīto(-ās) bitkarti(-es) mainot vērtības starp norā
msgid "Level (with Channel)"
msgstr "Līmenis (ar kanālu)"
-#: ../src/extension/internal/bitmap/levelChannel.cpp:54 ../src/extension/internal/filter/color.h:636
+#: ../src/extension/internal/bitmap/levelChannel.cpp:54 ../src/extension/internal/filter/color.h:711
msgid "Channel:"
msgstr "Kanāls:"
@@ -5192,7 +5192,7 @@ msgstr "Ēnot atlasīto(-ās) bitkarti(-es) ar šķietamu, attālinātu gaismas
msgid "Sharpen selected bitmap(s)"
msgstr "Palielināt atlasītās(-o) bitkartes(-šu) asumu"
-#: ../src/extension/internal/bitmap/solarize.cpp:39 ../src/extension/internal/filter/color.h:1494 ../src/extension/internal/filter/color.h:1498
+#: ../src/extension/internal/bitmap/solarize.cpp:39 ../src/extension/internal/filter/color.h:1569 ../src/extension/internal/filter/color.h:1573
msgid "Solarize"
msgstr "Solarizācija"
@@ -5527,15 +5527,16 @@ msgstr "Gaismas krāsa"
#: ../src/extension/internal/filter/bevels.h:62 ../src/extension/internal/filter/bevels.h:143 ../src/extension/internal/filter/bevels.h:227 ../src/extension/internal/filter/blurs.h:62 ../src/extension/internal/filter/blurs.h:131
#: ../src/extension/internal/filter/blurs.h:200 ../src/extension/internal/filter/blurs.h:266 ../src/extension/internal/filter/blurs.h:350 ../src/extension/internal/filter/bumps.h:141 ../src/extension/internal/filter/bumps.h:361
-#: ../src/extension/internal/filter/color.h:81 ../src/extension/internal/filter/color.h:170 ../src/extension/internal/filter/color.h:261 ../src/extension/internal/filter/color.h:346 ../src/extension/internal/filter/color.h:436
-#: ../src/extension/internal/filter/color.h:531 ../src/extension/internal/filter/color.h:653 ../src/extension/internal/filter/color.h:750 ../src/extension/internal/filter/color.h:829 ../src/extension/internal/filter/color.h:920
-#: ../src/extension/internal/filter/color.h:1048 ../src/extension/internal/filter/color.h:1118 ../src/extension/internal/filter/color.h:1211 ../src/extension/internal/filter/color.h:1323 ../src/extension/internal/filter/color.h:1428
-#: ../src/extension/internal/filter/color.h:1504 ../src/extension/internal/filter/color.h:1615 ../src/extension/internal/filter/distort.h:95 ../src/extension/internal/filter/distort.h:204 ../src/extension/internal/filter/filter-file.cpp:151
-#: ../src/extension/internal/filter/filter.cpp:214 ../src/extension/internal/filter/image.h:61 ../src/extension/internal/filter/morphology.h:75 ../src/extension/internal/filter/morphology.h:202 ../src/extension/internal/filter/overlays.h:79
-#: ../src/extension/internal/filter/paint.h:112 ../src/extension/internal/filter/paint.h:243 ../src/extension/internal/filter/paint.h:362 ../src/extension/internal/filter/paint.h:506 ../src/extension/internal/filter/paint.h:601
-#: ../src/extension/internal/filter/paint.h:724 ../src/extension/internal/filter/paint.h:876 ../src/extension/internal/filter/paint.h:980 ../src/extension/internal/filter/protrusions.h:54 ../src/extension/internal/filter/shadows.h:80
-#: ../src/extension/internal/filter/textures.h:90 ../src/extension/internal/filter/transparency.h:69 ../src/extension/internal/filter/transparency.h:140 ../src/extension/internal/filter/transparency.h:214
-#: ../src/extension/internal/filter/transparency.h:287 ../src/extension/internal/filter/transparency.h:349 ../src/ui/dialog/inkscape-preferences.cpp:1751
+#: ../src/extension/internal/filter/color.h:82 ../src/extension/internal/filter/color.h:171 ../src/extension/internal/filter/color.h:282 ../src/extension/internal/filter/color.h:336 ../src/extension/internal/filter/color.h:421
+#: ../src/extension/internal/filter/color.h:511 ../src/extension/internal/filter/color.h:606 ../src/extension/internal/filter/color.h:728 ../src/extension/internal/filter/color.h:825 ../src/extension/internal/filter/color.h:904
+#: ../src/extension/internal/filter/color.h:995 ../src/extension/internal/filter/color.h:1123 ../src/extension/internal/filter/color.h:1193 ../src/extension/internal/filter/color.h:1286 ../src/extension/internal/filter/color.h:1398
+#: ../src/extension/internal/filter/color.h:1503 ../src/extension/internal/filter/color.h:1579 ../src/extension/internal/filter/color.h:1690 ../src/extension/internal/filter/distort.h:95 ../src/extension/internal/filter/distort.h:204
+#: ../src/extension/internal/filter/filter-file.cpp:151 ../src/extension/internal/filter/filter.cpp:214 ../src/extension/internal/filter/image.h:61 ../src/extension/internal/filter/morphology.h:75
+#: ../src/extension/internal/filter/morphology.h:202 ../src/extension/internal/filter/overlays.h:79 ../src/extension/internal/filter/paint.h:112 ../src/extension/internal/filter/paint.h:243 ../src/extension/internal/filter/paint.h:362
+#: ../src/extension/internal/filter/paint.h:506 ../src/extension/internal/filter/paint.h:601 ../src/extension/internal/filter/paint.h:724 ../src/extension/internal/filter/paint.h:876 ../src/extension/internal/filter/paint.h:980
+#: ../src/extension/internal/filter/protrusions.h:54 ../src/extension/internal/filter/shadows.h:80 ../src/extension/internal/filter/textures.h:90 ../src/extension/internal/filter/transparency.h:69
+#: ../src/extension/internal/filter/transparency.h:140 ../src/extension/internal/filter/transparency.h:214 ../src/extension/internal/filter/transparency.h:287 ../src/extension/internal/filter/transparency.h:349
+#: ../src/ui/dialog/inkscape-preferences.cpp:1751
msgid "Filters"
msgstr "Filtri"
@@ -5547,7 +5548,7 @@ msgstr "Vienkāršs izkliedēts slīpums faktūru veidošanai"
msgid "Matte Jelly"
msgstr "Matēta želeja"
-#: ../src/extension/internal/filter/bevels.h:136 ../src/extension/internal/filter/bevels.h:220 ../src/extension/internal/filter/blurs.h:187 ../src/extension/internal/filter/color.h:74
+#: ../src/extension/internal/filter/bevels.h:136 ../src/extension/internal/filter/bevels.h:220 ../src/extension/internal/filter/blurs.h:187 ../src/extension/internal/filter/color.h:75
msgid "Brightness"
msgstr "Spilgtums"
@@ -5600,25 +5601,25 @@ msgid "Blend:"
msgstr "Sapludināt:"
#: ../src/extension/internal/filter/blurs.h:192 ../src/extension/internal/filter/blurs.h:339 ../src/extension/internal/filter/bumps.h:131 ../src/extension/internal/filter/bumps.h:337 ../src/extension/internal/filter/bumps.h:344
-#: ../src/extension/internal/filter/color.h:329 ../src/extension/internal/filter/color.h:336 ../src/extension/internal/filter/color.h:1423 ../src/extension/internal/filter/color.h:1596 ../src/extension/internal/filter/color.h:1602
+#: ../src/extension/internal/filter/color.h:404 ../src/extension/internal/filter/color.h:411 ../src/extension/internal/filter/color.h:1498 ../src/extension/internal/filter/color.h:1671 ../src/extension/internal/filter/color.h:1677
#: ../src/extension/internal/filter/paint.h:705 ../src/extension/internal/filter/transparency.h:63 ../src/filter-enums.cpp:55
msgid "Darken"
msgstr "Padarīt tumšāku"
#: ../src/extension/internal/filter/blurs.h:193 ../src/extension/internal/filter/blurs.h:340 ../src/extension/internal/filter/bumps.h:132 ../src/extension/internal/filter/bumps.h:335 ../src/extension/internal/filter/bumps.h:342
-#: ../src/extension/internal/filter/color.h:327 ../src/extension/internal/filter/color.h:332 ../src/extension/internal/filter/color.h:647 ../src/extension/internal/filter/color.h:1415 ../src/extension/internal/filter/color.h:1420
-#: ../src/extension/internal/filter/color.h:1594 ../src/extension/internal/filter/paint.h:703 ../src/extension/internal/filter/transparency.h:62 ../src/filter-enums.cpp:54 ../src/ui/dialog/input.cpp:382
+#: ../src/extension/internal/filter/color.h:402 ../src/extension/internal/filter/color.h:407 ../src/extension/internal/filter/color.h:722 ../src/extension/internal/filter/color.h:1490 ../src/extension/internal/filter/color.h:1495
+#: ../src/extension/internal/filter/color.h:1669 ../src/extension/internal/filter/paint.h:703 ../src/extension/internal/filter/transparency.h:62 ../src/filter-enums.cpp:54 ../src/ui/dialog/input.cpp:382
msgid "Screen"
msgstr "Ekrāns"
#: ../src/extension/internal/filter/blurs.h:194 ../src/extension/internal/filter/blurs.h:341 ../src/extension/internal/filter/bumps.h:133 ../src/extension/internal/filter/bumps.h:338 ../src/extension/internal/filter/bumps.h:345
-#: ../src/extension/internal/filter/color.h:325 ../src/extension/internal/filter/color.h:333 ../src/extension/internal/filter/color.h:645 ../src/extension/internal/filter/color.h:1414 ../src/extension/internal/filter/color.h:1421
-#: ../src/extension/internal/filter/color.h:1595 ../src/extension/internal/filter/color.h:1601 ../src/extension/internal/filter/paint.h:701 ../src/extension/internal/filter/transparency.h:60 ../src/filter-enums.cpp:53
+#: ../src/extension/internal/filter/color.h:400 ../src/extension/internal/filter/color.h:408 ../src/extension/internal/filter/color.h:720 ../src/extension/internal/filter/color.h:1489 ../src/extension/internal/filter/color.h:1496
+#: ../src/extension/internal/filter/color.h:1670 ../src/extension/internal/filter/color.h:1676 ../src/extension/internal/filter/paint.h:701 ../src/extension/internal/filter/transparency.h:60 ../src/filter-enums.cpp:53
msgid "Multiply"
msgstr "Pavairot"
#: ../src/extension/internal/filter/blurs.h:195 ../src/extension/internal/filter/blurs.h:342 ../src/extension/internal/filter/bumps.h:134 ../src/extension/internal/filter/bumps.h:339 ../src/extension/internal/filter/bumps.h:346
-#: ../src/extension/internal/filter/color.h:328 ../src/extension/internal/filter/color.h:335 ../src/extension/internal/filter/color.h:1422 ../src/extension/internal/filter/color.h:1593 ../src/extension/internal/filter/paint.h:704
+#: ../src/extension/internal/filter/color.h:403 ../src/extension/internal/filter/color.h:410 ../src/extension/internal/filter/color.h:1497 ../src/extension/internal/filter/color.h:1668 ../src/extension/internal/filter/paint.h:704
#: ../src/extension/internal/filter/transparency.h:64 ../src/filter-enums.cpp:56
msgid "Lighten"
msgstr "Padarīt gaišāku"
@@ -5649,7 +5650,7 @@ msgstr "Paplašināšana"
msgid "Erosion"
msgstr "Erozija"
-#: ../src/extension/internal/filter/blurs.h:336 ../src/extension/internal/filter/color.h:1205 ../src/extension/internal/filter/color.h:1317 ../src/ui/dialog/document-properties.cpp:122
+#: ../src/extension/internal/filter/blurs.h:336 ../src/extension/internal/filter/color.h:1280 ../src/extension/internal/filter/color.h:1392 ../src/ui/dialog/document-properties.cpp:122
msgid "Background color"
msgstr "Fona krāsa"
@@ -5657,9 +5658,9 @@ msgstr "Fona krāsa"
msgid "Blend type:"
msgstr "Sajaukšanas tips:"
-#: ../src/extension/internal/filter/blurs.h:338 ../src/extension/internal/filter/bumps.h:130 ../src/extension/internal/filter/bumps.h:336 ../src/extension/internal/filter/bumps.h:343 ../src/extension/internal/filter/color.h:326
-#: ../src/extension/internal/filter/color.h:334 ../src/extension/internal/filter/color.h:646 ../src/extension/internal/filter/color.h:1413 ../src/extension/internal/filter/color.h:1419 ../src/extension/internal/filter/color.h:1586
-#: ../src/extension/internal/filter/color.h:1600 ../src/extension/internal/filter/distort.h:78 ../src/extension/internal/filter/paint.h:702 ../src/extension/internal/filter/textures.h:77 ../src/extension/internal/filter/transparency.h:61
+#: ../src/extension/internal/filter/blurs.h:338 ../src/extension/internal/filter/bumps.h:130 ../src/extension/internal/filter/bumps.h:336 ../src/extension/internal/filter/bumps.h:343 ../src/extension/internal/filter/color.h:401
+#: ../src/extension/internal/filter/color.h:409 ../src/extension/internal/filter/color.h:721 ../src/extension/internal/filter/color.h:1488 ../src/extension/internal/filter/color.h:1494 ../src/extension/internal/filter/color.h:1661
+#: ../src/extension/internal/filter/color.h:1675 ../src/extension/internal/filter/distort.h:78 ../src/extension/internal/filter/paint.h:702 ../src/extension/internal/filter/textures.h:77 ../src/extension/internal/filter/transparency.h:61
#: ../src/filter-enums.cpp:52 ../src/ui/dialog/inkscape-preferences.cpp:653
msgid "Normal"
msgstr "Normāls"
@@ -5688,17 +5689,17 @@ msgstr "Reljefa vienkāršošana"
msgid "Bump source"
msgstr "Reljefa avots"
-#: ../src/extension/internal/filter/bumps.h:88 ../src/extension/internal/filter/bumps.h:317 ../src/extension/internal/filter/color.h:157 ../src/extension/internal/filter/color.h:637 ../src/extension/internal/filter/color.h:821
+#: ../src/extension/internal/filter/bumps.h:88 ../src/extension/internal/filter/bumps.h:317 ../src/extension/internal/filter/color.h:158 ../src/extension/internal/filter/color.h:712 ../src/extension/internal/filter/color.h:896
#: ../src/extension/internal/filter/transparency.h:132 ../src/filter-enums.cpp:128 ../src/ui/tools/flood-tool.cpp:183 ../src/widgets/sp-color-icc-selector.cpp:330 ../src/widgets/sp-color-scales.cpp:415 ../src/widgets/sp-color-scales.cpp:416
msgid "Red"
msgstr "Sarkans"
-#: ../src/extension/internal/filter/bumps.h:89 ../src/extension/internal/filter/bumps.h:318 ../src/extension/internal/filter/color.h:158 ../src/extension/internal/filter/color.h:638 ../src/extension/internal/filter/color.h:822
+#: ../src/extension/internal/filter/bumps.h:89 ../src/extension/internal/filter/bumps.h:318 ../src/extension/internal/filter/color.h:159 ../src/extension/internal/filter/color.h:713 ../src/extension/internal/filter/color.h:897
#: ../src/extension/internal/filter/transparency.h:133 ../src/filter-enums.cpp:129 ../src/ui/tools/flood-tool.cpp:184 ../src/widgets/sp-color-icc-selector.cpp:331 ../src/widgets/sp-color-scales.cpp:418 ../src/widgets/sp-color-scales.cpp:419
msgid "Green"
msgstr "Zaļš"
-#: ../src/extension/internal/filter/bumps.h:90 ../src/extension/internal/filter/bumps.h:319 ../src/extension/internal/filter/color.h:159 ../src/extension/internal/filter/color.h:639 ../src/extension/internal/filter/color.h:823
+#: ../src/extension/internal/filter/bumps.h:90 ../src/extension/internal/filter/bumps.h:319 ../src/extension/internal/filter/color.h:160 ../src/extension/internal/filter/color.h:714 ../src/extension/internal/filter/color.h:898
#: ../src/extension/internal/filter/transparency.h:134 ../src/filter-enums.cpp:130 ../src/ui/tools/flood-tool.cpp:185 ../src/widgets/sp-color-icc-selector.cpp:332 ../src/widgets/sp-color-scales.cpp:421 ../src/widgets/sp-color-scales.cpp:422
msgid "Blue"
msgstr "Zils"
@@ -5719,11 +5720,11 @@ msgstr "Atspīdums"
msgid "Diffuse"
msgstr "Izkliedēt"
-#: ../src/extension/internal/filter/bumps.h:98 ../src/extension/internal/filter/bumps.h:329 ../src/libgdl/gdl-dock-placeholder.c:175 ../src/libgdl/gdl-dock.c:199 ../src/widgets/rect-toolbar.cpp:335 ../share/extensions/interp_att_g.inx.h:11
+#: ../src/extension/internal/filter/bumps.h:98 ../src/extension/internal/filter/bumps.h:329 ../src/libgdl/gdl-dock-placeholder.c:175 ../src/libgdl/gdl-dock.c:199 ../src/widgets/rect-toolbar.cpp:334 ../share/extensions/interp_att_g.inx.h:11
msgid "Height"
msgstr "Augstums"
-#: ../src/extension/internal/filter/bumps.h:99 ../src/extension/internal/filter/bumps.h:330 ../src/extension/internal/filter/color.h:76 ../src/extension/internal/filter/color.h:824 ../src/extension/internal/filter/color.h:1113
+#: ../src/extension/internal/filter/bumps.h:99 ../src/extension/internal/filter/bumps.h:330 ../src/extension/internal/filter/color.h:77 ../src/extension/internal/filter/color.h:899 ../src/extension/internal/filter/color.h:1188
#: ../src/extension/internal/filter/paint.h:86 ../src/extension/internal/filter/paint.h:592 ../src/extension/internal/filter/paint.h:707 ../src/ui/tools/flood-tool.cpp:188 ../src/widgets/sp-color-icc-selector.cpp:341
#: ../src/widgets/sp-color-scales.cpp:447 ../src/widgets/sp-color-scales.cpp:448 ../src/widgets/tweak-toolbar.cpp:318 ../share/extensions/color_randomize.inx.h:5
msgid "Lightness"
@@ -5837,7 +5838,7 @@ msgstr "Aizmiglots attēls"
msgid "Background opacity"
msgstr "Fona necaurspīdība"
-#: ../src/extension/internal/filter/bumps.h:327 ../src/extension/internal/filter/color.h:1040
+#: ../src/extension/internal/filter/bumps.h:327 ../src/extension/internal/filter/color.h:1115
msgid "Lighting"
msgstr "Apgaismojums"
@@ -5873,397 +5874,441 @@ msgstr "Pēc"
msgid "Turns an image to jelly"
msgstr "Pārvērš attēlu želejā"
-#: ../src/extension/internal/filter/color.h:72
+#: ../src/extension/internal/filter/color.h:73
msgid "Brilliance"
msgstr "Mirdzums"
-#: ../src/extension/internal/filter/color.h:75 ../src/extension/internal/filter/color.h:1417
+#: ../src/extension/internal/filter/color.h:76 ../src/extension/internal/filter/color.h:1492
msgid "Over-saturation"
msgstr "Pārsātināšana"
-#: ../src/extension/internal/filter/color.h:77 ../src/extension/internal/filter/color.h:161 ../src/extension/internal/filter/overlays.h:70 ../src/extension/internal/filter/paint.h:85 ../src/extension/internal/filter/paint.h:502
+#: ../src/extension/internal/filter/color.h:78 ../src/extension/internal/filter/color.h:162 ../src/extension/internal/filter/overlays.h:70 ../src/extension/internal/filter/paint.h:85 ../src/extension/internal/filter/paint.h:502
#: ../src/extension/internal/filter/transparency.h:136 ../src/extension/internal/filter/transparency.h:210
msgid "Inverted"
msgstr "Apgriezts"
-#: ../src/extension/internal/filter/color.h:85
+#: ../src/extension/internal/filter/color.h:86
msgid "Brightness filter"
msgstr "Spilgtuma filtrs"
-#: ../src/extension/internal/filter/color.h:152
+#: ../src/extension/internal/filter/color.h:153
msgid "Channel Painting"
msgstr "Kanālu krāsosana"
-#: ../src/extension/internal/filter/color.h:156 ../src/extension/internal/filter/color.h:257 ../src/extension/internal/filter/paint.h:87 ../src/filter-enums.cpp:66 ../src/ui/dialog/inkscape-preferences.cpp:952
+#: ../src/extension/internal/filter/color.h:157 ../src/extension/internal/filter/color.h:332 ../src/extension/internal/filter/paint.h:87 ../src/filter-enums.cpp:66 ../src/ui/dialog/inkscape-preferences.cpp:952
#: ../src/ui/tools/flood-tool.cpp:187 ../src/widgets/sp-color-icc-selector.cpp:337 ../src/widgets/sp-color-icc-selector.cpp:342 ../src/widgets/sp-color-scales.cpp:444 ../src/widgets/sp-color-scales.cpp:445 ../src/widgets/tweak-toolbar.cpp:302
#: ../share/extensions/color_randomize.inx.h:4
msgid "Saturation"
msgstr "Piesātinājums"
-#: ../src/extension/internal/filter/color.h:160 ../src/extension/internal/filter/transparency.h:135 ../src/filter-enums.cpp:131 ../src/ui/tools/flood-tool.cpp:189
+#: ../src/extension/internal/filter/color.h:161 ../src/extension/internal/filter/transparency.h:135 ../src/filter-enums.cpp:131 ../src/ui/tools/flood-tool.cpp:189
msgid "Alpha"
msgstr "Alfa"
-#: ../src/extension/internal/filter/color.h:174
+#: ../src/extension/internal/filter/color.h:175
msgid "Replace RGB by any color"
msgstr "Aizvietot RGB ar jebkuru krāsu"
#: ../src/extension/internal/filter/color.h:254
+msgid "Color Blindness"
+msgstr ""
+
+#: ../src/extension/internal/filter/color.h:258
+msgid "Blindness type:"
+msgstr ""
+
+#: ../src/extension/internal/filter/color.h:259
+msgid "Rod monochromacy (atypical achromatopsia)"
+msgstr ""
+
+#: ../src/extension/internal/filter/color.h:260
+msgid "Cone monochromacy (typical achromatopsia)"
+msgstr ""
+
+#: ../src/extension/internal/filter/color.h:261
+msgid "Geen weak (deuteranomaly)"
+msgstr ""
+
+#: ../src/extension/internal/filter/color.h:262
+msgid "Green blind (deuteranopia)"
+msgstr ""
+
+#: ../src/extension/internal/filter/color.h:263
+msgid "Red weak (protanomaly)"
+msgstr ""
+
+#: ../src/extension/internal/filter/color.h:264
+msgid "Red blind (protanopia)"
+msgstr ""
+
+#: ../src/extension/internal/filter/color.h:265
+msgid "Blue weak (tritanomaly)"
+msgstr ""
+
+#: ../src/extension/internal/filter/color.h:266
+msgid "Blue blind (tritanopia)"
+msgstr ""
+
+#: ../src/extension/internal/filter/color.h:286
+msgid "Simulate color blindness"
+msgstr "Simulēt krāsu aklumu"
+
+#: ../src/extension/internal/filter/color.h:329
msgid "Color Shift"
msgstr "Krāsu pārbīde"
-#: ../src/extension/internal/filter/color.h:256
+#: ../src/extension/internal/filter/color.h:331
msgid "Shift (°)"
msgstr "Pārbīde (°)"
-#: ../src/extension/internal/filter/color.h:265
+#: ../src/extension/internal/filter/color.h:340
msgid "Rotate and desaturate hue"
msgstr "Pagriezt un atsātināt nokrāsu"
-#: ../src/extension/internal/filter/color.h:321
+#: ../src/extension/internal/filter/color.h:396
msgid "Harsh light"
msgstr "Asa gaisma"
-#: ../src/extension/internal/filter/color.h:322
+#: ../src/extension/internal/filter/color.h:397
msgid "Normal light"
msgstr "Parasta gaisma"
-#: ../src/extension/internal/filter/color.h:323
+#: ../src/extension/internal/filter/color.h:398
msgid "Duotone"
msgstr "Divtoņu"
-#: ../src/extension/internal/filter/color.h:324 ../src/extension/internal/filter/color.h:1412
+#: ../src/extension/internal/filter/color.h:399 ../src/extension/internal/filter/color.h:1487
msgid "Blend 1:"
msgstr "Sapludinājums 1:"
-#: ../src/extension/internal/filter/color.h:331 ../src/extension/internal/filter/color.h:1418
+#: ../src/extension/internal/filter/color.h:406 ../src/extension/internal/filter/color.h:1493
msgid "Blend 2:"
msgstr "Sapludinājums 2:"
-#: ../src/extension/internal/filter/color.h:350
+#: ../src/extension/internal/filter/color.h:425
msgid "Blend image or object with a flood color"
msgstr "Sapludināt attēlu vai objektu ar pludināšanas krāsu"
-#: ../src/extension/internal/filter/color.h:424 ../src/filter-enums.cpp:23
+#: ../src/extension/internal/filter/color.h:499 ../src/filter-enums.cpp:23
msgid "Component Transfer"
msgstr "Sastāvdaļu pārnese"
-#: ../src/extension/internal/filter/color.h:427 ../src/filter-enums.cpp:110
+#: ../src/extension/internal/filter/color.h:502 ../src/filter-enums.cpp:110
msgid "Identity"
msgstr "Identitāte"
-#: ../src/extension/internal/filter/color.h:428 ../src/extension/internal/filter/paint.h:498 ../src/filter-enums.cpp:111 ../src/ui/dialog/filter-effects-dialog.cpp:1050
+#: ../src/extension/internal/filter/color.h:503 ../src/extension/internal/filter/paint.h:498 ../src/filter-enums.cpp:111 ../src/ui/dialog/filter-effects-dialog.cpp:1050
msgid "Table"
msgstr "Tabula"
-#: ../src/extension/internal/filter/color.h:429 ../src/extension/internal/filter/paint.h:499 ../src/filter-enums.cpp:112 ../src/ui/dialog/filter-effects-dialog.cpp:1053
+#: ../src/extension/internal/filter/color.h:504 ../src/extension/internal/filter/paint.h:499 ../src/filter-enums.cpp:112 ../src/ui/dialog/filter-effects-dialog.cpp:1053
msgid "Discrete"
msgstr "Atsevišķs"
-#: ../src/extension/internal/filter/color.h:430 ../src/filter-enums.cpp:113 ../src/live_effects/lpe-interpolate_points.cpp:25 ../src/live_effects/lpe-powerstroke.cpp:194
+#: ../src/extension/internal/filter/color.h:505 ../src/filter-enums.cpp:113 ../src/live_effects/lpe-interpolate_points.cpp:25 ../src/live_effects/lpe-powerstroke.cpp:194
msgid "Linear"
msgstr "Lineārs"
-#: ../src/extension/internal/filter/color.h:431 ../src/filter-enums.cpp:114
+#: ../src/extension/internal/filter/color.h:506 ../src/filter-enums.cpp:114
msgid "Gamma"
msgstr "Gamma"
-#: ../src/extension/internal/filter/color.h:440
+#: ../src/extension/internal/filter/color.h:515
msgid "Basic component transfer structure"
msgstr "Pamata komponentu pārneses struktūra"
-#: ../src/extension/internal/filter/color.h:509
+#: ../src/extension/internal/filter/color.h:584
msgid "Duochrome"
msgstr "Divkrāsu"
-#: ../src/extension/internal/filter/color.h:513
+#: ../src/extension/internal/filter/color.h:588
msgid "Fluorescence level"
msgstr "Fluorescences līmenis"
-#: ../src/extension/internal/filter/color.h:514
+#: ../src/extension/internal/filter/color.h:589
msgid "Swap:"
msgstr "Apmainīt:"
-#: ../src/extension/internal/filter/color.h:515
+#: ../src/extension/internal/filter/color.h:590
msgid "No swap"
msgstr "Nav pieejama maiņvieta (swap)"
-#: ../src/extension/internal/filter/color.h:516
+#: ../src/extension/internal/filter/color.h:591
msgid "Color and alpha"
msgstr "Krāsu un alfa"
-#: ../src/extension/internal/filter/color.h:517
+#: ../src/extension/internal/filter/color.h:592
msgid "Color only"
msgstr "Tikai krāsu"
-#: ../src/extension/internal/filter/color.h:518
+#: ../src/extension/internal/filter/color.h:593
msgid "Alpha only"
msgstr "Tikai alfa"
-#: ../src/extension/internal/filter/color.h:522
+#: ../src/extension/internal/filter/color.h:597
msgid "Color 1"
msgstr "1. krāsa"
-#: ../src/extension/internal/filter/color.h:525
+#: ../src/extension/internal/filter/color.h:600
msgid "Color 2"
msgstr "2. krāsa"
-#: ../src/extension/internal/filter/color.h:535
+#: ../src/extension/internal/filter/color.h:610
msgid "Convert luminance values to a duochrome palette"
msgstr "Pārvērst spilgtuma vērtības par divkrāsu paleti"
-#: ../src/extension/internal/filter/color.h:634
+#: ../src/extension/internal/filter/color.h:709
msgid "Extract Channel"
msgstr "Ekstraģēt kanālu"
-#: ../src/extension/internal/filter/color.h:640 ../src/widgets/sp-color-icc-selector.cpp:344 ../src/widgets/sp-color-icc-selector.cpp:349 ../src/widgets/sp-color-scales.cpp:469 ../src/widgets/sp-color-scales.cpp:470
+#: ../src/extension/internal/filter/color.h:715 ../src/widgets/sp-color-icc-selector.cpp:344 ../src/widgets/sp-color-icc-selector.cpp:349 ../src/widgets/sp-color-scales.cpp:469 ../src/widgets/sp-color-scales.cpp:470
msgid "Cyan"
msgstr "Ciāns"
-#: ../src/extension/internal/filter/color.h:641 ../src/widgets/sp-color-icc-selector.cpp:345 ../src/widgets/sp-color-icc-selector.cpp:350 ../src/widgets/sp-color-scales.cpp:472 ../src/widgets/sp-color-scales.cpp:473
+#: ../src/extension/internal/filter/color.h:716 ../src/widgets/sp-color-icc-selector.cpp:345 ../src/widgets/sp-color-icc-selector.cpp:350 ../src/widgets/sp-color-scales.cpp:472 ../src/widgets/sp-color-scales.cpp:473
msgid "Magenta"
msgstr "Fuksīns (Magenta)"
-#: ../src/extension/internal/filter/color.h:642 ../src/widgets/sp-color-icc-selector.cpp:346 ../src/widgets/sp-color-icc-selector.cpp:351 ../src/widgets/sp-color-scales.cpp:475 ../src/widgets/sp-color-scales.cpp:476
+#: ../src/extension/internal/filter/color.h:717 ../src/widgets/sp-color-icc-selector.cpp:346 ../src/widgets/sp-color-icc-selector.cpp:351 ../src/widgets/sp-color-scales.cpp:475 ../src/widgets/sp-color-scales.cpp:476
msgid "Yellow"
msgstr "Dzeltens"
-#: ../src/extension/internal/filter/color.h:644
+#: ../src/extension/internal/filter/color.h:719
msgid "Background blend mode:"
msgstr "Fona sajaukšanas veids:"
-#: ../src/extension/internal/filter/color.h:649
+#: ../src/extension/internal/filter/color.h:724
msgid "Channel to alpha"
msgstr "Kanālu uz alfa"
-#: ../src/extension/internal/filter/color.h:657
+#: ../src/extension/internal/filter/color.h:732
msgid "Extract color channel as a transparent image"
msgstr "Ekstraģēt krāsa kanālu kā caurspīdīgu attēlu"
-#: ../src/extension/internal/filter/color.h:740
+#: ../src/extension/internal/filter/color.h:815
msgid "Fade to Black or White"
msgstr "Izgaisināt melnā vai baltā"
-#: ../src/extension/internal/filter/color.h:743
+#: ../src/extension/internal/filter/color.h:818
msgid "Fade to:"
msgstr "Izgaisināt:"
-#: ../src/extension/internal/filter/color.h:744 ../src/ui/widget/selected-style.cpp:274 ../src/widgets/sp-color-icc-selector.cpp:347 ../src/widgets/sp-color-scales.cpp:478 ../src/widgets/sp-color-scales.cpp:479
+#: ../src/extension/internal/filter/color.h:819 ../src/ui/widget/selected-style.cpp:274 ../src/widgets/sp-color-icc-selector.cpp:347 ../src/widgets/sp-color-scales.cpp:478 ../src/widgets/sp-color-scales.cpp:479
msgid "Black"
msgstr "Melns"
-#: ../src/extension/internal/filter/color.h:745 ../src/ui/widget/selected-style.cpp:270
+#: ../src/extension/internal/filter/color.h:820 ../src/ui/widget/selected-style.cpp:270
msgid "White"
msgstr "Balts"
-#: ../src/extension/internal/filter/color.h:754
+#: ../src/extension/internal/filter/color.h:829
msgid "Fade to black or white"
msgstr "Izgaisināt melnā vai baltā"
-#: ../src/extension/internal/filter/color.h:819
+#: ../src/extension/internal/filter/color.h:894
msgid "Greyscale"
msgstr "Pelēktoņu"
-#: ../src/extension/internal/filter/color.h:825 ../src/extension/internal/filter/paint.h:83 ../src/extension/internal/filter/paint.h:239
+#: ../src/extension/internal/filter/color.h:900 ../src/extension/internal/filter/paint.h:83 ../src/extension/internal/filter/paint.h:239
msgid "Transparent"
msgstr "Caurspīdīgs"
-#: ../src/extension/internal/filter/color.h:833
+#: ../src/extension/internal/filter/color.h:908
msgid "Customize greyscale components"
msgstr "Pieskaņojiet pelēktoņu sastāvdaļas"
-#: ../src/extension/internal/filter/color.h:905 ../src/ui/widget/selected-style.cpp:266
+#: ../src/extension/internal/filter/color.h:980 ../src/ui/widget/selected-style.cpp:266
msgid "Invert"
msgstr "Invertēt"
-#: ../src/extension/internal/filter/color.h:907
+#: ../src/extension/internal/filter/color.h:982
msgid "Invert channels:"
msgstr "Invertēt kanālus:"
-#: ../src/extension/internal/filter/color.h:908
+#: ../src/extension/internal/filter/color.h:983
msgid "No inversion"
msgstr "Nav inversijas"
-#: ../src/extension/internal/filter/color.h:909
+#: ../src/extension/internal/filter/color.h:984
msgid "Red and blue"
msgstr "Sarkans un zils"
-#: ../src/extension/internal/filter/color.h:910
+#: ../src/extension/internal/filter/color.h:985
msgid "Red and green"
msgstr "Sarkans un zaļs"
-#: ../src/extension/internal/filter/color.h:911
+#: ../src/extension/internal/filter/color.h:986
msgid "Green and blue"
msgstr "Zaļš un zils"
-#: ../src/extension/internal/filter/color.h:913
+#: ../src/extension/internal/filter/color.h:988
msgid "Light transparency"
msgstr "Viegls caurspīdīgums"
-#: ../src/extension/internal/filter/color.h:914
+#: ../src/extension/internal/filter/color.h:989
msgid "Invert hue"
msgstr "Invertēt nokrāsu"
-#: ../src/extension/internal/filter/color.h:915
+#: ../src/extension/internal/filter/color.h:990
msgid "Invert lightness"
msgstr "Invertēt gaišumu"
-#: ../src/extension/internal/filter/color.h:916
+#: ../src/extension/internal/filter/color.h:991
msgid "Invert transparency"
msgstr "Invertēt caurspīdīgumu"
-#: ../src/extension/internal/filter/color.h:924
+#: ../src/extension/internal/filter/color.h:999
msgid "Manage hue, lightness and transparency inversions"
msgstr "Vadiet nokrāsas, gaišuma un caurspīdīguma inversijas"
-#: ../src/extension/internal/filter/color.h:1042
+#: ../src/extension/internal/filter/color.h:1117
msgid "Lights"
msgstr "Gaismas"
-#: ../src/extension/internal/filter/color.h:1043
+#: ../src/extension/internal/filter/color.h:1118
msgid "Shadows"
msgstr "Ēnas"
-#: ../src/extension/internal/filter/color.h:1044 ../src/extension/internal/filter/paint.h:356 ../src/filter-enums.cpp:33 ../src/live_effects/effect.cpp:110 ../src/ui/dialog/filter-effects-dialog.cpp:1047
+#: ../src/extension/internal/filter/color.h:1119 ../src/extension/internal/filter/paint.h:356 ../src/filter-enums.cpp:33 ../src/live_effects/effect.cpp:110 ../src/ui/dialog/filter-effects-dialog.cpp:1047
#: ../src/widgets/gradient-toolbar.cpp:1159
msgid "Offset"
msgstr "Nobīde"
-#: ../src/extension/internal/filter/color.h:1052
+#: ../src/extension/internal/filter/color.h:1127
msgid "Modify lights and shadows separately"
msgstr "Mainīt gaismas un ēnas atsevišķi"
-#: ../src/extension/internal/filter/color.h:1111
+#: ../src/extension/internal/filter/color.h:1186
msgid "Lightness-Contrast"
msgstr "Spilgtums-kontrasts"
-#: ../src/extension/internal/filter/color.h:1122
+#: ../src/extension/internal/filter/color.h:1197
msgid "Modify lightness and contrast separately"
msgstr "Mainīt gaišumu un kontrastu atsevišķi"
-#: ../src/extension/internal/filter/color.h:1190
+#: ../src/extension/internal/filter/color.h:1265
msgid "Nudge RGB"
msgstr "Nobīdīt RGB"
-#: ../src/extension/internal/filter/color.h:1194
+#: ../src/extension/internal/filter/color.h:1269
msgid "Red offset"
msgstr "Sarkanā nobīde"
-#: ../src/extension/internal/filter/color.h:1195 ../src/extension/internal/filter/color.h:1198 ../src/extension/internal/filter/color.h:1201 ../src/extension/internal/filter/color.h:1307 ../src/extension/internal/filter/color.h:1310
-#: ../src/extension/internal/filter/color.h:1313 ../src/ui/dialog/input.cpp:1616 ../src/ui/dialog/layers.cpp:917
+#: ../src/extension/internal/filter/color.h:1270 ../src/extension/internal/filter/color.h:1273 ../src/extension/internal/filter/color.h:1276 ../src/extension/internal/filter/color.h:1382 ../src/extension/internal/filter/color.h:1385
+#: ../src/extension/internal/filter/color.h:1388 ../src/ui/dialog/input.cpp:1616 ../src/ui/dialog/layers.cpp:917
msgid "X"
msgstr "X"
-#: ../src/extension/internal/filter/color.h:1196 ../src/extension/internal/filter/color.h:1199 ../src/extension/internal/filter/color.h:1202 ../src/extension/internal/filter/color.h:1308 ../src/extension/internal/filter/color.h:1311
-#: ../src/extension/internal/filter/color.h:1314 ../src/ui/dialog/input.cpp:1616
+#: ../src/extension/internal/filter/color.h:1271 ../src/extension/internal/filter/color.h:1274 ../src/extension/internal/filter/color.h:1277 ../src/extension/internal/filter/color.h:1383 ../src/extension/internal/filter/color.h:1386
+#: ../src/extension/internal/filter/color.h:1389 ../src/ui/dialog/input.cpp:1616
msgid "Y"
msgstr "Y"
-#: ../src/extension/internal/filter/color.h:1197
+#: ../src/extension/internal/filter/color.h:1272
msgid "Green offset"
msgstr "Zaļa nobīde"
-#: ../src/extension/internal/filter/color.h:1200
+#: ../src/extension/internal/filter/color.h:1275
msgid "Blue offset"
msgstr "Zilā nobīde"
-#: ../src/extension/internal/filter/color.h:1215
+#: ../src/extension/internal/filter/color.h:1290
msgid "Nudge RGB channels separately and blend them to different types of backgrounds"
msgstr "Nobīdīt RGB kanālus atsevišķi vienu no otra un sajaukt tos dažādu fona krāsu iegūšanai"
-#: ../src/extension/internal/filter/color.h:1302
+#: ../src/extension/internal/filter/color.h:1377
msgid "Nudge CMY"
msgstr "Nobīdīt CMY"
-#: ../src/extension/internal/filter/color.h:1306
+#: ../src/extension/internal/filter/color.h:1381
msgid "Cyan offset"
msgstr "Ciāna nobīde"
-#: ../src/extension/internal/filter/color.h:1309
+#: ../src/extension/internal/filter/color.h:1384
msgid "Magenta offset"
msgstr "Fuksīna nobīde:"
-#: ../src/extension/internal/filter/color.h:1312
+#: ../src/extension/internal/filter/color.h:1387
msgid "Yellow offset"
msgstr "Dzeltenā nobīde"
-#: ../src/extension/internal/filter/color.h:1327
+#: ../src/extension/internal/filter/color.h:1402
msgid "Nudge CMY channels separately and blend them to different types of backgrounds"
msgstr "Nobīdīt CMY kanālus atsevišķi vienu no otra un sajaukt tos dažādu fona krāsu iegūšanai"
-#: ../src/extension/internal/filter/color.h:1408
+#: ../src/extension/internal/filter/color.h:1483
msgid "Quadritone fantasy"
msgstr "Četrtoņu fantāzija"
-#: ../src/extension/internal/filter/color.h:1410
+#: ../src/extension/internal/filter/color.h:1485
msgid "Hue distribution (°)"
msgstr "Nokrāsas sadale (°)"
-#: ../src/extension/internal/filter/color.h:1411 ../share/extensions/svgcalendar.inx.h:19
+#: ../src/extension/internal/filter/color.h:1486 ../share/extensions/svgcalendar.inx.h:19
msgid "Colors"
msgstr "Krāsas"
-#: ../src/extension/internal/filter/color.h:1432
+#: ../src/extension/internal/filter/color.h:1507
msgid "Replace hue by two colors"
msgstr "Aizvietot nokrāsu ar divām krāsām"
-#: ../src/extension/internal/filter/color.h:1496
+#: ../src/extension/internal/filter/color.h:1571
msgid "Hue rotation (°)"
msgstr "Nokrāsas griešana (°)"
-#: ../src/extension/internal/filter/color.h:1499
+#: ../src/extension/internal/filter/color.h:1574
msgid "Moonarize"
msgstr "Mēnessgaisma"
-#: ../src/extension/internal/filter/color.h:1508
+#: ../src/extension/internal/filter/color.h:1583
msgid "Classic photographic solarization effect"
msgstr "Klasiskais foto solarizācijas efekts"
-#: ../src/extension/internal/filter/color.h:1581
+#: ../src/extension/internal/filter/color.h:1656
msgid "Tritone"
msgstr "Trīstoņu"
-#: ../src/extension/internal/filter/color.h:1587
+#: ../src/extension/internal/filter/color.h:1662
msgid "Enhance hue"
msgstr "Pastiprināt nokrāsu"
-#: ../src/extension/internal/filter/color.h:1588
+#: ../src/extension/internal/filter/color.h:1663
msgid "Phosphorescence"
msgstr "Fosforescence"
-#: ../src/extension/internal/filter/color.h:1589
+#: ../src/extension/internal/filter/color.h:1664
msgid "Colored nights"
msgstr "Krāsainās naktis"
-#: ../src/extension/internal/filter/color.h:1590
+#: ../src/extension/internal/filter/color.h:1665
msgid "Hue to background"
msgstr "Nokrāsu par fonu"
-#: ../src/extension/internal/filter/color.h:1592
+#: ../src/extension/internal/filter/color.h:1667
msgid "Global blend:"
msgstr "Vispārējā sapludināšana"
-#: ../src/extension/internal/filter/color.h:1598
+#: ../src/extension/internal/filter/color.h:1673
msgid "Glow"
msgstr "Spīdums"
-#: ../src/extension/internal/filter/color.h:1599
+#: ../src/extension/internal/filter/color.h:1674
msgid "Glow blend:"
msgstr "Kvēlojošā sapludināšana:"
-#: ../src/extension/internal/filter/color.h:1604
+#: ../src/extension/internal/filter/color.h:1679
msgid "Local light"
msgstr "Vietējā gaisma"
-#: ../src/extension/internal/filter/color.h:1605
+#: ../src/extension/internal/filter/color.h:1680
msgid "Global light"
msgstr "Vispārējā gaisma"
-#: ../src/extension/internal/filter/color.h:1608
+#: ../src/extension/internal/filter/color.h:1683
msgid "Hue distribution (°):"
msgstr "Nokrāsas sadale (°):"
-#: ../src/extension/internal/filter/color.h:1619
+#: ../src/extension/internal/filter/color.h:1694
msgid "Create a custom tritone palette with additional glow, blend modes and hue moving"
msgstr "Izveido pielāgotu triju toņu paleti ar papildu spīdumu, sajaukšanas režīmiem un nokrāsas pārvietošanos"
@@ -6396,7 +6441,7 @@ msgstr "Ārējs"
msgid "Open"
msgstr "Atvērt"
-#: ../src/extension/internal/filter/morphology.h:65 ../src/libgdl/gdl-dock-placeholder.c:167 ../src/libgdl/gdl-dock.c:191 ../src/widgets/rect-toolbar.cpp:318 ../src/widgets/spray-toolbar.cpp:116 ../src/widgets/tweak-toolbar.cpp:128
+#: ../src/extension/internal/filter/morphology.h:65 ../src/libgdl/gdl-dock-placeholder.c:167 ../src/libgdl/gdl-dock.c:191 ../src/widgets/rect-toolbar.cpp:317 ../src/widgets/spray-toolbar.cpp:116 ../src/widgets/tweak-toolbar.cpp:128
#: ../share/extensions/interp_att_g.inx.h:10
msgid "Width"
msgstr "Platums"
@@ -7586,7 +7631,7 @@ msgstr "Griezt nokrāsu"
msgid "Luminance to Alpha"
msgstr "Spilgtumu par alfa"
-#: ../src/filter-enums.cpp:87 ../src/widgets/mesh-toolbar.cpp:476 ../share/extensions/jessyInk_mouseHandler.inx.h:3 ../share/extensions/jessyInk_transitions.inx.h:7
+#: ../src/filter-enums.cpp:87 ../share/extensions/jessyInk_mouseHandler.inx.h:3 ../share/extensions/jessyInk_transitions.inx.h:7
msgid "Default"
msgstr "Noklusētais"
@@ -8509,50 +8554,52 @@ msgstr "Vizuālās robežas"
msgid "Uses the visual bounding box"
msgstr "Izmanto vizuālo robežrāmi"
-#. initialise your parameters here:
-#. testpointA(_("Test Point A"), _("Test A"), "ptA", &wr, this,
-#. Geom::Point(100,100)),
-#: ../src/live_effects/lpe-bspline.cpp:60
+#: ../src/live_effects/lpe-bspline.cpp:57
msgid "Steps with CTRL:"
msgstr "Soļi ar CTRL:"
-#: ../src/live_effects/lpe-bspline.cpp:60
+#: ../src/live_effects/lpe-bspline.cpp:57
msgid "Change number of steps with CTRL pressed"
msgstr "Mainiet soļu skaitu, turot nospiestu CTRL"
-#: ../src/live_effects/lpe-bspline.cpp:61
+#: ../src/live_effects/lpe-bspline.cpp:58 ../src/live_effects/lpe-simplify.cpp:33
+#, fuzzy
+msgid "Helper size:"
+msgstr "Subversion palīgprogramma"
+
+#: ../src/live_effects/lpe-bspline.cpp:58 ../src/live_effects/lpe-simplify.cpp:33
+#, fuzzy
+msgid "Helper size"
+msgstr "Subversion palīgprogramma"
+
+#: ../src/live_effects/lpe-bspline.cpp:59
msgid "Ignore cusp nodes"
msgstr "Neņemt vērā asos mezglus"
-#: ../src/live_effects/lpe-bspline.cpp:61
+#: ../src/live_effects/lpe-bspline.cpp:59
msgid "Change ignoring cusp nodes"
msgstr "Mainīt, neņemot vērā asos mezglus"
-#: ../src/live_effects/lpe-bspline.cpp:62 ../src/live_effects/lpe-fillet-chamfer.cpp:57
+#: ../src/live_effects/lpe-bspline.cpp:60 ../src/live_effects/lpe-fillet-chamfer.cpp:57
msgid "Change only selected nodes"
msgstr "Mainīt tikai atlasītos mezglus"
-#: ../src/live_effects/lpe-bspline.cpp:63
-#, fuzzy
-msgid "Show helper paths"
-msgstr "Rādīt pārvietojumus starp ceļiem"
-
-#: ../src/live_effects/lpe-bspline.cpp:64
+#: ../src/live_effects/lpe-bspline.cpp:61
#, fuzzy
msgid "Change weight:"
msgstr "Svars"
-#: ../src/live_effects/lpe-bspline.cpp:64
+#: ../src/live_effects/lpe-bspline.cpp:61
#, fuzzy
msgid "Change weight of the effect"
msgstr "Filtra efektu apgabala augstums"
-#: ../src/live_effects/lpe-bspline.cpp:291
+#: ../src/live_effects/lpe-bspline.cpp:290
#, fuzzy
msgid "Default weight"
msgstr "Noklusētais virsraksts"
-#: ../src/live_effects/lpe-bspline.cpp:296
+#: ../src/live_effects/lpe-bspline.cpp:295
msgid "Make cusp"
msgstr "Pārvērst par aso"
@@ -9037,202 +9084,202 @@ msgid "Control handle 0:"
msgstr "Vadības turis 0:"
#: ../src/live_effects/lpe-lattice2.cpp:47
-msgid "Control handle 0 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 0 - Ctrl+Alt+Click, lai atiestatītu "
+msgid "Control handle 0 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:48
msgid "Control handle 1:"
msgstr "Vadības turis 1:"
#: ../src/live_effects/lpe-lattice2.cpp:48
-msgid "Control handle 1 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 1 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 1 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:49
msgid "Control handle 2:"
msgstr "Vadības turis 2:"
#: ../src/live_effects/lpe-lattice2.cpp:49
-msgid "Control handle 2 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 2 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 2 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:50
msgid "Control handle 3:"
msgstr "Vadības turis 3:"
#: ../src/live_effects/lpe-lattice2.cpp:50
-msgid "Control handle 3 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 3 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 3 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:51
msgid "Control handle 4:"
msgstr "Vadības turis 4:"
#: ../src/live_effects/lpe-lattice2.cpp:51
-msgid "Control handle 4 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 4 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 4 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:52
msgid "Control handle 5:"
msgstr "Vadības turis 5:"
#: ../src/live_effects/lpe-lattice2.cpp:52
-msgid "Control handle 5 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 5 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 5 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:53
msgid "Control handle 6:"
msgstr "Vadības turis 6:"
#: ../src/live_effects/lpe-lattice2.cpp:53
-msgid "Control handle 6 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 6 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 6 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:54
msgid "Control handle 7:"
msgstr "Vadības turis 7:"
#: ../src/live_effects/lpe-lattice2.cpp:54
-msgid "Control handle 7 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 7 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 7 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:55
msgid "Control handle 8x9:"
msgstr "Vadības turis 8x9:"
#: ../src/live_effects/lpe-lattice2.cpp:55
-msgid "Control handle 8x9 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 8x9 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 8x9 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:56
msgid "Control handle 10x11:"
msgstr "Vadības turis 10x11:"
#: ../src/live_effects/lpe-lattice2.cpp:56
-msgid "Control handle 10x11 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 10x11 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 10x11 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:57
msgid "Control handle 12:"
msgstr "Vadības turis 12:"
#: ../src/live_effects/lpe-lattice2.cpp:57
-msgid "Control handle 12 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 12 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 12 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:58
msgid "Control handle 13:"
msgstr "Vadības turis 13:"
#: ../src/live_effects/lpe-lattice2.cpp:58
-msgid "Control handle 13 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 13 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 13 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:59
msgid "Control handle 14:"
msgstr "Vadības turis 14:"
#: ../src/live_effects/lpe-lattice2.cpp:59
-msgid "Control handle 14 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 14 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 14 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:60
msgid "Control handle 15:"
msgstr "Vadības turis 15:"
#: ../src/live_effects/lpe-lattice2.cpp:60
-msgid "Control handle 15 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 15 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 15 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:61
msgid "Control handle 16:"
msgstr "Vadības turis 16:"
#: ../src/live_effects/lpe-lattice2.cpp:61
-msgid "Control handle 16 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 16 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 16 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:62
msgid "Control handle 17:"
msgstr "Vadības turis 17:"
#: ../src/live_effects/lpe-lattice2.cpp:62
-msgid "Control handle 17 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 17 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 17 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:63
msgid "Control handle 18:"
msgstr "Vadības turis 18:"
#: ../src/live_effects/lpe-lattice2.cpp:63
-msgid "Control handle 18 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 18 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 18 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:64
msgid "Control handle 19:"
msgstr "Vadības turis 19:"
#: ../src/live_effects/lpe-lattice2.cpp:64
-msgid "Control handle 19 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 19 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 19 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:65
msgid "Control handle 20x21:"
msgstr "Vadības turis 20x21:"
#: ../src/live_effects/lpe-lattice2.cpp:65
-msgid "Control handle 20x21 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 20x21 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 20x21 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:66
msgid "Control handle 22x23:"
msgstr "Vadības turis 22x23:"
#: ../src/live_effects/lpe-lattice2.cpp:66
-msgid "Control handle 22x23 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 22x23 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 22x23 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:67
msgid "Control handle 24x26:"
msgstr "Vadības turis 24x26:"
#: ../src/live_effects/lpe-lattice2.cpp:67
-msgid "Control handle 24x26 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 24x26 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 24x26 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:68
msgid "Control handle 25x27:"
msgstr "Vadības turis 25x27:"
#: ../src/live_effects/lpe-lattice2.cpp:68
-msgid "Control handle 25x27 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 25x27 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 25x27 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:69
msgid "Control handle 28x30:"
msgstr "Vadības turis 28x30:"
#: ../src/live_effects/lpe-lattice2.cpp:69
-msgid "Control handle 28x30 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 28x30 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 28x30 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:70
msgid "Control handle 29x31:"
msgstr "Vadības turis 29x31:"
#: ../src/live_effects/lpe-lattice2.cpp:70
-msgid "Control handle 29x31 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 29x31 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 29x31 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-lattice2.cpp:71
msgid "Control handle 32x33x34x35:"
msgstr "Vadības turis 32x33x34x35:"
#: ../src/live_effects/lpe-lattice2.cpp:71
-msgid "Control handle 32x33x34x35 - Ctrl+Alt+Click to reset"
-msgstr "Vadības turis 32x33x34x35 - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Control handle 32x33x34x35 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
-#: ../src/live_effects/lpe-lattice2.cpp:221
+#: ../src/live_effects/lpe-lattice2.cpp:224
#, fuzzy
msgid "Reset grid"
msgstr "Atstatīt"
@@ -9344,32 +9391,32 @@ msgid "Top Left"
msgstr "Augšējais kreisais"
#: ../src/live_effects/lpe-perspective-envelope.cpp:47
-msgid "Top Left - Ctrl+Alt+Click to reset"
-msgstr "Augšējais kreisais - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Top Left - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-perspective-envelope.cpp:48
msgid "Top Right"
msgstr "Augšējais labais"
#: ../src/live_effects/lpe-perspective-envelope.cpp:48
-msgid "Top Right - Ctrl+Alt+Click to reset"
-msgstr "Augšējais labais - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Top Right - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-perspective-envelope.cpp:49
msgid "Down Left"
msgstr "Apakšējais kreisais"
#: ../src/live_effects/lpe-perspective-envelope.cpp:49
-msgid "Down Left - Ctrl+Alt+Click to reset"
-msgstr "Apakšējais kreisais - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Down Left - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-perspective-envelope.cpp:50
msgid "Down Right"
msgstr "Apakšējais labais"
#: ../src/live_effects/lpe-perspective-envelope.cpp:50
-msgid "Down Right - Ctrl+Alt+Click to reset"
-msgstr "Apakšējais labais - Ctrl+Alt+Click, lai atiestatītu"
+msgid "Down Right - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"
+msgstr ""
#: ../src/live_effects/lpe-perspective-envelope.cpp:257
msgid "Handles:"
@@ -9760,64 +9807,62 @@ msgstr "Pagriezt mezglus"
msgid "The \"show handles\" path effect will remove any custom style on the object you are applying it to. If this is not what you want, click Cancel."
msgstr "Ceļa efekts \"rādīt turus\" atcels jebkuru pielāgoto stilu objektam, kuram to pielietosiet. Ja tas tas, ko sagaidāt, nospiediet Atcelt."
-#: ../src/live_effects/lpe-simplify.cpp:29
+#: ../src/live_effects/lpe-simplify.cpp:30
msgid "Steps:"
msgstr "Soļi:"
-#: ../src/live_effects/lpe-simplify.cpp:29
+#: ../src/live_effects/lpe-simplify.cpp:30
msgid "Change number of simplify steps "
msgstr "Norādiet vienkāršošanas soļu skaitu"
-#: ../src/live_effects/lpe-simplify.cpp:30
+#: ../src/live_effects/lpe-simplify.cpp:31
#, fuzzy
msgid "Roughly threshold:"
msgstr "S_lieksnis..."
-#: ../src/live_effects/lpe-simplify.cpp:31
-#, fuzzy
-msgid "Helper size:"
-msgstr "Subversion palīgprogramma"
-
-#: ../src/live_effects/lpe-simplify.cpp:31
-#, fuzzy
-msgid "Helper size"
-msgstr "Subversion palīgprogramma"
+#: ../src/live_effects/lpe-simplify.cpp:32
+msgid "Smooth angles:"
+msgstr ""
#: ../src/live_effects/lpe-simplify.cpp:32
+msgid "Max degree difference on handles to preform a smooth"
+msgstr ""
+
+#: ../src/live_effects/lpe-simplify.cpp:34
#, fuzzy
msgid "Helper nodes"
msgstr "Subversion palīgprogramma"
-#: ../src/live_effects/lpe-simplify.cpp:32
+#: ../src/live_effects/lpe-simplify.cpp:34
#, fuzzy
msgid "Show helper nodes"
msgstr "Rādīt pārveidošanas turus atsevišķiem mezgliem"
-#: ../src/live_effects/lpe-simplify.cpp:34
+#: ../src/live_effects/lpe-simplify.cpp:36
#, fuzzy
msgid "Helper handles"
msgstr "Subversion palīgprogramma"
-#: ../src/live_effects/lpe-simplify.cpp:34
+#: ../src/live_effects/lpe-simplify.cpp:36
#, fuzzy
msgid "Show helper handles"
msgstr "Rādīt turus"
-#: ../src/live_effects/lpe-simplify.cpp:36
+#: ../src/live_effects/lpe-simplify.cpp:38
#, fuzzy
msgid "Paths separately"
msgstr "Vienkāršo ceļus (atsevišķi):"
-#: ../src/live_effects/lpe-simplify.cpp:36
+#: ../src/live_effects/lpe-simplify.cpp:38
msgid "Simplifying paths (separately)"
msgstr "Vienkāršo ceļus (atsevišķi)"
-#: ../src/live_effects/lpe-simplify.cpp:38
+#: ../src/live_effects/lpe-simplify.cpp:40
#, fuzzy
msgid "Just coalesce"
msgstr "Tikai tagad..."
-#: ../src/live_effects/lpe-simplify.cpp:38
+#: ../src/live_effects/lpe-simplify.cpp:40
#, fuzzy
msgid "Simplify just coalesce"
msgstr "Vienkāršot:"
@@ -10158,7 +10203,7 @@ msgstr "Piesaistīt ceļam starpliktuvē"
msgid "Paste path parameter"
msgstr "Ielīmēt ceļa parametru"
-#: ../src/live_effects/parameter/point.cpp:89 ../src/live_effects/parameter/pointreseteable.cpp:103
+#: ../src/live_effects/parameter/point.cpp:103
msgid "Change point parameter"
msgstr "Mainīt punkta parametru"
@@ -11325,11 +11370,11 @@ msgstr "Izmantojiet <b>Shift+D</b>, lai sameklētu rāmi"
#: ../src/selection-describer.cpp:236
#, c-format
-msgid "<b>%i</b> objects selected of type %s"
-msgid_plural "<b>%i</b> objects selected of types %s"
-msgstr[0] "izvēlēts <b>%i</b> objekts ar tipu %s"
-msgstr[1] "izvēlēti <b>%i</b> objekti ar tipu %s"
-msgstr[2] "izvēlēti <b>%i</b> objekti ar tipu %s"
+msgid "<b>%1$i</b> objects selected of type %2$s"
+msgid_plural "<b>%1$i</b> objects selected of types %2$s"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
#: ../src/selection-describer.cpp:246
#, c-format
@@ -17611,7 +17656,7 @@ msgid "Filter effects quality for display"
msgstr "Filtru efektu kvalitāte attēlošanai uz ekrāna"
#. build custom preferences tab
-#: ../src/ui/dialog/inkscape-preferences.cpp:1428 ../src/ui/dialog/print.cpp:232
+#: ../src/ui/dialog/inkscape-preferences.cpp:1428 ../src/ui/dialog/print.cpp:215
msgid "Rendering"
msgstr "Renderēšana"
@@ -17928,7 +17973,7 @@ msgstr "Aparatūra"
msgid "Link:"
msgstr "Saite:"
-#: ../src/ui/dialog/input.cpp:742 ../src/ui/dialog/input.cpp:743 ../src/ui/dialog/input.cpp:1571 ../src/widgets/mesh-toolbar.cpp:499
+#: ../src/ui/dialog/input.cpp:742 ../src/ui/dialog/input.cpp:743 ../src/ui/dialog/input.cpp:1571
msgid "None"
msgstr "Neviens"
@@ -18736,20 +18781,20 @@ msgstr "Izkārtot gar elipsi"
msgid "Could not open temporary PNG for bitmap printing"
msgstr "Nav iespējams atvērt pagaidu PNG bitkartes drukāšanai"
-#: ../src/ui/dialog/print.cpp:155
+#: ../src/ui/dialog/print.cpp:138
msgid "Could not set up Document"
msgstr "Neizdevās izveidot dokumentu"
-#: ../src/ui/dialog/print.cpp:159
+#: ../src/ui/dialog/print.cpp:142
msgid "Failed to set CairoRenderContext"
msgstr "Neizdevās iestatīt CairoRenderContext"
#. set up dialog title, based on document name
-#: ../src/ui/dialog/print.cpp:197
+#: ../src/ui/dialog/print.cpp:180
msgid "SVG Document"
msgstr "SVG dokuments"
-#: ../src/ui/dialog/print.cpp:198
+#: ../src/ui/dialog/print.cpp:181
msgid "Print"
msgstr "Drukāt"
@@ -21399,7 +21444,7 @@ msgstr "MetadataLicence|Citas"
#: ../src/ui/widget/licensor.cpp:72
msgid "Document license updated"
-msgstr ""
+msgstr "Dokumenta licence atsvaidzināta"
#: ../src/ui/widget/object-composite-settings.cpp:47 ../src/ui/widget/selected-style.cpp:1119 ../src/ui/widget/selected-style.cpp:1120
msgid "Opacity (%)"
@@ -24293,14 +24338,14 @@ msgstr "Loks: mainīt sākumu/beigas"
msgid "Arc: Change open/closed"
msgstr "Loks: mainīt uz atvērtu/slēgtu"
-#: ../src/widgets/arc-toolbar.cpp:289 ../src/widgets/arc-toolbar.cpp:319 ../src/widgets/rect-toolbar.cpp:261 ../src/widgets/rect-toolbar.cpp:300 ../src/widgets/spiral-toolbar.cpp:214 ../src/widgets/spiral-toolbar.cpp:238
+#: ../src/widgets/arc-toolbar.cpp:289 ../src/widgets/arc-toolbar.cpp:319 ../src/widgets/rect-toolbar.cpp:260 ../src/widgets/rect-toolbar.cpp:299 ../src/widgets/spiral-toolbar.cpp:214 ../src/widgets/spiral-toolbar.cpp:238
#: ../src/widgets/star-toolbar.cpp:384 ../src/widgets/star-toolbar.cpp:446
msgid "<b>New:</b>"
msgstr "<b>Jauns:</b>"
#. FIXME: implement averaging of all parameters for multiple selected
#. gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>"));
-#: ../src/widgets/arc-toolbar.cpp:292 ../src/widgets/arc-toolbar.cpp:303 ../src/widgets/rect-toolbar.cpp:269 ../src/widgets/rect-toolbar.cpp:287 ../src/widgets/spiral-toolbar.cpp:216 ../src/widgets/spiral-toolbar.cpp:227
+#: ../src/widgets/arc-toolbar.cpp:292 ../src/widgets/arc-toolbar.cpp:303 ../src/widgets/rect-toolbar.cpp:268 ../src/widgets/rect-toolbar.cpp:286 ../src/widgets/spiral-toolbar.cpp:216 ../src/widgets/spiral-toolbar.cpp:227
#: ../src/widgets/star-toolbar.cpp:386
msgid "<b>Change:</b>"
msgstr "<b>Mainīt:</b>"
@@ -25225,7 +25270,7 @@ msgid "Display measuring info for selected items"
msgstr "Rādīt atlasīto objektu mērījumu informāciju"
#. Add the units menu.
-#: ../src/widgets/lpe-toolbar.cpp:387 ../src/widgets/node-toolbar.cpp:613 ../src/widgets/paintbucket-toolbar.cpp:168 ../src/widgets/rect-toolbar.cpp:379 ../src/widgets/select-toolbar.cpp:538
+#: ../src/widgets/lpe-toolbar.cpp:387 ../src/widgets/node-toolbar.cpp:613 ../src/widgets/paintbucket-toolbar.cpp:168 ../src/widgets/rect-toolbar.cpp:378 ../src/widgets/select-toolbar.cpp:538
msgid "Units"
msgstr "Mērvienības"
@@ -25254,7 +25299,7 @@ msgid "The units to be used for the measurements"
msgstr "Mērīšanai izmantojamās mērvienības"
#: ../src/widgets/mesh-toolbar.cpp:311
-msgid "Set mesh smoothing"
+msgid "Set mesh type"
msgstr ""
#: ../src/widgets/mesh-toolbar.cpp:334
@@ -25322,47 +25367,27 @@ msgid "Show side and tensor handles"
msgstr "Rādīt malas un tenzora turus"
#: ../src/widgets/mesh-toolbar.cpp:463
-msgid "WARNING: Mesh SVG Syntax Subject to Change, Smoothing Experimental"
+msgid "WARNING: Mesh SVG Syntax Subject to Change"
msgstr ""
#: ../src/widgets/mesh-toolbar.cpp:473
-msgctxt "Smoothing"
-msgid "None"
-msgstr ""
-
-#: ../src/widgets/mesh-toolbar.cpp:479
-msgid "Smooth1"
-msgstr ""
-
-#: ../src/widgets/mesh-toolbar.cpp:482
-msgid "Smooth2"
-msgstr ""
-
-#: ../src/widgets/mesh-toolbar.cpp:485
-msgid "Smooth3"
-msgstr ""
-
-#: ../src/widgets/mesh-toolbar.cpp:488
-msgid "Smooth4"
-msgstr ""
-
-#: ../src/widgets/mesh-toolbar.cpp:491
-msgid "Smooth5"
+msgctxt "Type"
+msgid "Coons"
msgstr ""
-#: ../src/widgets/mesh-toolbar.cpp:494
-msgid "Smooth6"
+#: ../src/widgets/mesh-toolbar.cpp:476
+msgid "Bicubic"
msgstr ""
-#: ../src/widgets/mesh-toolbar.cpp:497
-msgid "Smooth7"
+#: ../src/widgets/mesh-toolbar.cpp:478
+msgid "Coons"
msgstr ""
-#: ../src/widgets/mesh-toolbar.cpp:500
-msgid "If the mesh should be smoothed across patch boundaries."
+#: ../src/widgets/mesh-toolbar.cpp:479
+msgid "Coons: no smoothing. Bicubic: smoothing across patch boundaries."
msgstr ""
-#: ../src/widgets/mesh-toolbar.cpp:502 ../src/widgets/pencil-toolbar.cpp:278
+#: ../src/widgets/mesh-toolbar.cpp:481 ../src/widgets/pencil-toolbar.cpp:278
msgid "Smoothing:"
msgstr "Nogludināšana:"
@@ -25771,55 +25796,55 @@ msgstr "Atiestatīt zīmuļa parametrus uz noklusētajiem (izmantojiet Inkscape
msgid "Change rectangle"
msgstr "Izveidot taisnstūri"
-#: ../src/widgets/rect-toolbar.cpp:318
+#: ../src/widgets/rect-toolbar.cpp:317
msgid "W:"
msgstr "P:"
-#: ../src/widgets/rect-toolbar.cpp:318
+#: ../src/widgets/rect-toolbar.cpp:317
msgid "Width of rectangle"
msgstr "Taisnstūra platums"
-#: ../src/widgets/rect-toolbar.cpp:335
+#: ../src/widgets/rect-toolbar.cpp:334
msgid "H:"
msgstr "H:"
-#: ../src/widgets/rect-toolbar.cpp:335
+#: ../src/widgets/rect-toolbar.cpp:334
msgid "Height of rectangle"
msgstr "Taisnstūra augstums"
-#: ../src/widgets/rect-toolbar.cpp:349 ../src/widgets/rect-toolbar.cpp:364
+#: ../src/widgets/rect-toolbar.cpp:348 ../src/widgets/rect-toolbar.cpp:363
msgid "not rounded"
msgstr "nav noapaļoti"
-#: ../src/widgets/rect-toolbar.cpp:352
+#: ../src/widgets/rect-toolbar.cpp:351
msgid "Horizontal radius"
msgstr "Horizontālais rādiuss"
-#: ../src/widgets/rect-toolbar.cpp:352
+#: ../src/widgets/rect-toolbar.cpp:351
msgid "Rx:"
msgstr "Rx:"
-#: ../src/widgets/rect-toolbar.cpp:352
+#: ../src/widgets/rect-toolbar.cpp:351
msgid "Horizontal radius of rounded corners"
msgstr "Noapaļoto stūru horizontālais rādiuss"
-#: ../src/widgets/rect-toolbar.cpp:367
+#: ../src/widgets/rect-toolbar.cpp:366
msgid "Vertical radius"
msgstr "Vertikālais rādiuss"
-#: ../src/widgets/rect-toolbar.cpp:367
+#: ../src/widgets/rect-toolbar.cpp:366
msgid "Ry:"
msgstr "Ry:"
-#: ../src/widgets/rect-toolbar.cpp:367
+#: ../src/widgets/rect-toolbar.cpp:366
msgid "Vertical radius of rounded corners"
msgstr "Noapaļoto stūru vertikālais rādiuss"
-#: ../src/widgets/rect-toolbar.cpp:386
+#: ../src/widgets/rect-toolbar.cpp:385
msgid "Not rounded"
msgstr "Nenoapaļoti"
-#: ../src/widgets/rect-toolbar.cpp:387
+#: ../src/widgets/rect-toolbar.cpp:386
msgid "Make corners sharp"
msgstr "Padarīt stūrus asus"
@@ -27194,7 +27219,7 @@ msgstr "Zema precizitāte vienkāršo ceļus, augsta precizitāte saglabā ceļa
msgid "Use the pressure of the input device to alter the force of tweak action"
msgstr "Izmantojiet spiedienu uz ievadierīci, lai mainītu pieskaņošanas darbības spēku"
-#: ../share/extensions/convert2dashes.py:93
+#: ../share/extensions/convert2dashes.py:100
msgid ""
"The selected object is not a path.\n"
"Try using the procedure Path->Object to Path."
@@ -27252,11 +27277,11 @@ msgstr "Atrastas un ignorētas %d POLYLINE tipa ENTITIES. Lūdzu, mēģiniet pā
msgid "Failed to import the numpy or numpy.linalg modules. These modules are required by this extension. Please install them and try again."
msgstr "Neizdevās importēt numpy vai numpy.linalg moduļus. Šie moduļi ir nepieciešami šim paplašinājuma. Lūdzu, uzstādiet tos un mēģiniet vēlreiz."
-#: ../share/extensions/dxf_outlines.py:300
+#: ../share/extensions/dxf_outlines.py:299
msgid "Error: Field 'Layer match name' must be filled when using 'By name match' option"
msgstr "Kļūda: laukam 'Slāņa nosaukuma atbilstība' jābūt aizpildītam, ja izmantojat 'Pēc nosaukuma atbilstības' papildiespēju"
-#: ../share/extensions/dxf_outlines.py:341
+#: ../share/extensions/dxf_outlines.py:340
#, python-format
msgid "Warning: Layer '%s' not found!"
msgstr "Uzmanību: slānis '%s' nav atrasts!"
@@ -27293,7 +27318,7 @@ msgid "Need at least 2 paths selected"
msgstr "Nepieciešami vismaz 2 atlasīti ceļi"
#: ../share/extensions/funcplot.py:48
-msgid "x-interval cannot be zero. Please modify 'Start X value' or 'End X alue'"
+msgid "x-interval cannot be zero. Please modify 'Start X value' or 'End X value'"
msgstr "x-intervāls nevar būt nulle. Lūdzu, mainiet 'Sākuma X' vai 'Beigu X' vērtības"
#: ../share/extensions/funcplot.py:60
@@ -28619,7 +28644,6 @@ msgid "Text Font:"
msgstr "Teksta fonts:"
#: ../share/extensions/dxf_input.inx.h:11
-#, fuzzy
msgid ""
"- AutoCAD Release 13 and newer.\n"
"- for manual scaling, assume dxf drawing is in mm.\n"
@@ -28631,10 +28655,12 @@ msgid ""
"- limited support for BLOCKS, use AutoCAD Explode Blocks instead, if needed."
msgstr ""
"- AutoCAD 13 un jaunākām versijām:\n"
-"- pieņemt, ka dxf rasējums ir mm.\n"
+"- mērogošanai ar roku pieņemt, ka dxf rasējums ir mm.\n"
"- pieņemt, ka svg rasējums ir pikseļos ar izšķirtspēju 96 dpi.\n"
"- mēroga koeficients un izejas punkts attiecas tikai uz rokas mērogošanu.\n"
-"- slāņi tiek saglabāti tikai Fails->Atvērt gadījumā, Importēt - nē.\n"
+"- 'Automātiskā mērogošana' ietilpinās platumu A4 lapā.\n"
+"- 'Lasīt no datnes' izmanto mainīgo $MEASUREMENT.\n"
+"- slāņi tiek saglabāti tikai Datne->Atvērt gadījumā, Importēt - nē.\n"
"- ierobežots BLOCKS atbalsts, nepieciešamības gadījumā izmantojiet AutoCAD Explode Blocks."
#: ../share/extensions/dxf_input.inx.h:19
@@ -31598,11 +31624,11 @@ msgstr "Izmantojamā komandu valoda. (Noklusētā: HPGL)"
#: ../share/extensions/plotter.inx.h:12
msgid "Initialization commands:"
-msgstr ""
+msgstr "Inicializēšanas komandas:"
#: ../share/extensions/plotter.inx.h:13
msgid "Commands that will be sent to the plotter before the main data stream, only use this if you know what you are doing! (Default: Empty)"
-msgstr ""
+msgstr "Komandas, kas tiks nosūtītas ploterim pirms galvenās datu plūsmas, izmantojiet to tikai gadījumā, ja saprotat, ko darāt (Noklusētais: tukšs)"
#: ../share/extensions/plotter.inx.h:14
msgid "Software (XON/XOFF)"
@@ -32363,11 +32389,11 @@ msgstr "Mērogojamo vektoru grafika"
msgid "Seamless Pattern"
msgstr "Pa_darīt viengabalainu"
-#: ../share/extensions/seamless_pattern.inx.h:2
+#: ../share/extensions/seamless_pattern.inx.h:2 ../share/extensions/seamless_pattern_procedural.inx.h:2
msgid "Custom Width (px):"
msgstr "Pielāgots platums (piks.):"
-#: ../share/extensions/seamless_pattern.inx.h:3
+#: ../share/extensions/seamless_pattern.inx.h:3 ../share/extensions/seamless_pattern_procedural.inx.h:3
msgid "Custom Height (px):"
msgstr "Pielāgot augstums (piks.):"
@@ -32380,14 +32406,6 @@ msgstr "Šis paplašinājums pārrakstīs atvērto dokumentu"
msgid "Seamless Pattern Procedural"
msgstr "Pa_darīt viengabalainu"
-#: ../share/extensions/seamless_pattern_procedural.inx.h:2
-msgid "Custom Width (px.):"
-msgstr "Pielāgots platums (piks.):"
-
-#: ../share/extensions/seamless_pattern_procedural.inx.h:3
-msgid "Custom Height (px.):"
-msgstr "Pielāgot augstums (piks.):"
-
#: ../share/extensions/setup_typography_canvas.inx.h:1
msgid "1 - Setup Typography Canvas"
msgstr "1 - Izveidot tipogrāfijas audeklu"
@@ -33266,6 +33284,112 @@ msgstr "Bieži lietots galeriju attēlu grafiskais formāts "
msgid "XAML Input"
msgstr "XAML ievade"
+#, fuzzy
+#~ msgid "Show helper paths"
+#~ msgstr "Rādīt pārvietojumus starp ceļiem"
+
+#~ msgid "Control handle 0 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 0 - Ctrl+Alt+Click, lai atiestatītu "
+
+#~ msgid "Control handle 1 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 1 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 2 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 2 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 3 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 3 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 4 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 4 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 5 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 5 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 6 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 6 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 7 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 7 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 8x9 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 8x9 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 10x11 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 10x11 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 12 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 12 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 13 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 13 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 14 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 14 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 15 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 15 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 16 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 16 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 17 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 17 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 18 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 18 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 19 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 19 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 20x21 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 20x21 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 22x23 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 22x23 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 24x26 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 24x26 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 25x27 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 25x27 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 28x30 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 28x30 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 29x31 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 29x31 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Control handle 32x33x34x35 - Ctrl+Alt+Click to reset"
+#~ msgstr "Vadības turis 32x33x34x35 - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Top Left - Ctrl+Alt+Click to reset"
+#~ msgstr "Augšējais kreisais - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Top Right - Ctrl+Alt+Click to reset"
+#~ msgstr "Augšējais labais - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Down Left - Ctrl+Alt+Click to reset"
+#~ msgstr "Apakšējais kreisais - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "Down Right - Ctrl+Alt+Click to reset"
+#~ msgstr "Apakšējais labais - Ctrl+Alt+Click, lai atiestatītu"
+
+#~ msgid "<b>%i</b> objects selected of type %s"
+#~ msgid_plural "<b>%i</b> objects selected of types %s"
+#~ msgstr[0] "izvēlēts <b>%i</b> objekts ar tipu %s"
+#~ msgstr[1] "izvēlēti <b>%i</b> objekti ar tipu %s"
+#~ msgstr[2] "izvēlēti <b>%i</b> objekti ar tipu %s"
+
+#~ msgid "x-interval cannot be zero. Please modify 'Start X value' or 'End X alue'"
+#~ msgstr "x-intervāls nevar būt nulle. Lūdzu, mainiet 'Sākuma X' vai 'Beigu X' vērtības"
+
+#~ msgid "Custom Width (px.):"
+#~ msgstr "Pielāgots platums (piks.):"
+
+#~ msgid "Custom Height (px.):"
+#~ msgstr "Pielāgot augstums (piks.):"
+
#~ msgid "Select a file of predefined shortcuts to use. Any customized shortcuts you create will be added seperately to "
#~ msgstr "Izvēlieties datni ar iepriekš definētām saīsnēm. Visas Jūsu izveidotās pielāgotās saīsnes tiks pievienotas pie "
diff --git a/share/extensions/restack.py b/share/extensions/restack.py
index 615b41527..507353025 100755
--- a/share/extensions/restack.py
+++ b/share/extensions/restack.py
@@ -54,9 +54,9 @@ class Restack(inkex.Effect):
svg = self.document.getroot()
parentnode = self.current_layer
file = self.args[ -1 ]
-
+
#get all bounding boxes in file by calling inkscape again with the --query-all command line option
- #it returns a comma seperated list structured id,x,y,w,h
+ #it returns a comma separated list structured id,x,y,w,h
if bsubprocess:
p = Popen('inkscape --query-all "%s"' % (file), shell=True, stdout=PIPE, stderr=PIPE)
err = p.stderr
@@ -65,12 +65,12 @@ class Restack(inkex.Effect):
reader=csv.CSVParser().parse_string(f) #there was a module cvs.py in earlier inkscape that behaved differently
except:
reader=csv.reader(f.split( os.linesep ))
- err.close()
+ err.close()
else:
_,f,err = os.popen3('inkscape --query-all "%s"' % ( file ) )
reader=csv.reader( f )
err.close()
-
+
#build a dictionary with id as the key
dimen = dict()
for line in reader:
diff --git a/share/extensions/text_extract.py b/share/extensions/text_extract.py
index bf263ef39..dfcddefdc 100755
--- a/share/extensions/text_extract.py
+++ b/share/extensions/text_extract.py
@@ -42,15 +42,15 @@ class Extract(inkex.Effect):
def __init__(self):
inkex.Effect.__init__(self)
self.OptionParser.add_option("-d", "--direction",
- action="store", type="string",
+ action="store", type="string",
dest="direction", default="tb",
help="direction to extract text")
self.OptionParser.add_option("-x", "--xanchor",
- action="store", type="string",
+ action="store", type="string",
dest="xanchor", default="m",
help="horizontal point to compare")
self.OptionParser.add_option("-y", "--yanchor",
- action="store", type="string",
+ action="store", type="string",
dest="yanchor", default="m",
help="vertical point to compare")
@@ -58,15 +58,15 @@ class Extract(inkex.Effect):
if len(self.selected)==0:
for node in self.document.xpath('//svg:text | //svg:flowRoot', namespaces=inkex.NSS):
self.selected[node.get('id')] = node
-
+
if len( self.selected ) > 0:
objlist = []
svg = self.document.getroot()
parentnode = self.current_layer
file = self.args[ -1 ]
-
- #get all bounding boxes in file by calling inkscape again with the --query-all command line option
- #it returns a comma seperated list structured id,x,y,w,h
+
+ # get all bounding boxes in file by calling inkscape again with the --query-all command line option
+ # it returns a comma separated list structured id,x,y,w,h
if bsubprocess:
p = Popen('inkscape --query-all "%s"' % (file), shell=True, stdout=PIPE, stderr=PIPE)
err = p.stderr
@@ -75,12 +75,12 @@ class Extract(inkex.Effect):
reader=csv.CSVParser().parse_string(f) #there was a module cvs.py in earlier inkscape that behaved differently
except:
reader=csv.reader(f.split( os.linesep ))
- err.close()
+ err.close()
else:
_,f,err = os.popen3('inkscape --query-all "%s"' % ( file ) )
reader=csv.reader( f )
err.close()
-
+
#build a dictionary with id as the key
dimen = dict()
for line in reader:
@@ -89,7 +89,7 @@ class Extract(inkex.Effect):
if not bsubprocess: #close file if opened using os.popen3
f.close
-
+
#find the center of all selected objects **Not the average!
x,y,w,h = dimen[self.selected.keys()[0]]
minx = x
@@ -131,7 +131,7 @@ class Extract(inkex.Effect):
cy = y + h
else: # middle
cy = y + h / 2
-
+
#direction chosen
if self.options.direction == "tb":
objlist.append([cy,id])
@@ -146,7 +146,7 @@ class Extract(inkex.Effect):
#move them to the top of the object stack in this order.
for item in objlist:
self.recurse(deepcopy(self.selected[item[1]]))
-
+
def recurse(self, node):
istext = (node.tag == '{http://www.w3.org/2000/svg}flowPara' or node.tag == '{http://www.w3.org/2000/svg}flowDiv' or node.tag == '{http://www.w3.org/2000/svg}text')
if node.text != None or node.tail != None:
diff --git a/share/extensions/text_merge.py b/share/extensions/text_merge.py
index dc6ee331c..625f14b75 100644
--- a/share/extensions/text_merge.py
+++ b/share/extensions/text_merge.py
@@ -73,8 +73,8 @@ class Merge(inkex.Effect):
parentnode = self.current_layer
file = self.args[ -1 ]
- #get all bounding boxes in file by calling inkscape again with the --query-all command line option
- #it returns a comma seperated list structured id,x,y,w,h
+ # get all bounding boxes in file by calling inkscape again with the --query-all command line option
+ # it returns a comma separated list structured id,x,y,w,h
if bsubprocess:
p = Popen('inkscape --query-all "%s"' % (file), shell=True, stdout=PIPE, stderr=PIPE)
err = p.stderr
diff --git a/share/keys/macromedia-freehand-mx.xml b/share/keys/macromedia-freehand-mx.xml
index 3512806bf..89069a217 100644
--- a/share/keys/macromedia-freehand-mx.xml
+++ b/share/keys/macromedia-freehand-mx.xml
@@ -35,7 +35,7 @@ File, Edit, View, Modify, Text, Xtras, Window, Help.
<bind key="F1" modifiers="Shift" action="ToolRect" display="true"/>
- <!-- Freehand has seperate tools for Ellipse and Arc unlike Inkscape. -->
+ <!-- Freehand has separate tools for Ellipse and Arc unlike Inkscape. -->
<bind key="F3" modifiers="Shift" action="ToolArc" display="true"/>
<!-- Star (Inkscape). Polygon (Freehand) inlcudes star options. -->
@@ -396,7 +396,7 @@ File, Edit, View, Modify, Text, Xtras, Window, Help.
<bind key="F3" modifiers="Ctrl" action="DialogFillStroke" display="true"/>
<bind action="DialogObjectProperties" />
- <!-- Freehand has a seperate find and replace for Text and Graphics -->
+ <!-- Freehand has a separate find and replace for Text and Graphics -->
<!-- Edit, Find And Replace, Graphics Ctrl+F -->
<bind key="f" modifiers="Ctrl" action="DialogFind" display="true"/>
<bind key="F" modifiers="Ctrl" action="DialogFind" />
diff --git a/src/2geom/line.h b/src/2geom/line.h
index ade67f818..cbd68fa08 100644
--- a/src/2geom/line.h
+++ b/src/2geom/line.h
@@ -35,6 +35,7 @@
#define LIB2GEOM_SEEN_LINE_H
#include <cmath>
+#include <iostream>
#include <boost/optional.hpp>
#include <2geom/bezier-curve.h> // for LineSegment
#include <2geom/rect.h>
@@ -258,9 +259,19 @@ public:
dist = -dot(n, m_origin);
return n;
}
- /// @}
+
+ friend inline std::ostream &operator<< (std::ostream &out_file, const Geom::Line &in_line);
+/// @}
}; // end class Line
+/** @brief Output operator for lines.
+ * Prints out representation (point + versor)
+ */
+inline std::ostream &operator<< (std::ostream &out_file, const Geom::Line &in_line) {
+ out_file << "X: " << in_line.m_origin[X] << " Y: " << in_line.m_origin[Y]
+ << " dX: " << in_line.m_versor[X] << " dY: " << in_line.m_versor[Y];
+ return out_file;
+}
inline
double distance(Point const& _point, Line const& _line)
@@ -365,6 +376,10 @@ inline
Line make_angle_bisector_line(Point const& A, Point const& O, Point const& B)
{
Point M = middle_point(A,B);
+ if (are_near(O,M)) {
+ Line l(A,B);
+ M += (make_orthogonal_line(O,l)).versor();
+ }
return Line(O,M);
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6659e8c0a..27c5e49db 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,4 +1,3 @@
-
# -----------------------------------------------------------------------------
# Define the main source
# -----------------------------------------------------------------------------
@@ -33,8 +32,8 @@ set(sp_SRC
sp-gradient-reference.cpp
sp-gradient.cpp
sp-guide.cpp
- sp-hatch.cpp
sp-hatch-path.cpp
+ sp-hatch.cpp
sp-image.cpp
sp-item-group.cpp
sp-item-notify-moveto.cpp
@@ -47,10 +46,10 @@ set(sp_SRC
sp-lpe-item.cpp
sp-marker.cpp
sp-mask.cpp
- sp-mesh.cpp
sp-mesh-array.cpp
sp-mesh-patch.cpp
sp-mesh-row.cpp
+ sp-mesh.cpp
sp-metadata.cpp
sp-missing-glyph.cpp
sp-namedview.cpp
@@ -75,6 +74,9 @@ set(sp_SRC
sp-style-elem.cpp
sp-switch.cpp
sp-symbol.cpp
+ sp-tag-use-reference.cpp
+ sp-tag-use.cpp
+ sp-tag.cpp
sp-text.cpp
sp-title.cpp
sp-tref-reference.cpp
@@ -119,8 +121,8 @@ set(sp_SRC
sp-guide-attachment.h
sp-guide-constraint.h
sp-guide.h
- sp-hatch.h
sp-hatch-path.h
+ sp-hatch.h
sp-image.h
sp-item-group.h
sp-item-notify-moveto.h
@@ -131,13 +133,13 @@ set(sp_SRC
sp-line.h
sp-linear-gradient.h
sp-lpe-item.h
- sp-marker.h
sp-marker-loc.h
+ sp-marker.h
sp-mask.h
- sp-mesh.h
sp-mesh-array.h
sp-mesh-patch.h
sp-mesh-row.h
+ sp-mesh.h
sp-metadata.h
sp-missing-glyph.h
sp-namedview.h
@@ -203,21 +205,17 @@ set(inkscape_SRC
filter-enums.cpp
gc-anchored.cpp
gc-finalized.cpp
- gc.cpp
gradient-chemistry.cpp
gradient-drag.cpp
graphlayout.cpp
guide-snapper.cpp
help.cpp
id-clash.cpp
- # ige-mac-menu.c
inkscape.cpp
- inkscape.rc
- interface.cpp
knot-holder-entity.cpp
+ knot-ptr.cpp
knot.cpp
knotholder.cpp
- knot-ptr.cpp
layer-fns.cpp
layer-manager.cpp
layer-model.cpp
@@ -257,8 +255,8 @@ set(inkscape_SRC
snapped-line.cpp
snapped-point.cpp
snapper.cpp
- style.cpp
style-internal.cpp
+ style.cpp
svg-view-widget.cpp
svg-view.cpp
text-chemistry.cpp
@@ -313,18 +311,12 @@ set(inkscape_SRC
event.h
extract-uri-test.h
extract-uri.h
- factory.h
file.h
fill-or-stroke.h
filter-chemistry.h
filter-enums.h
- gc-alloc.h
- gc-allocator.h
gc-anchored.h
- gc-core.h
gc-finalized.h
- gc-managed.h
- gc-soft-ptr.h
gradient-chemistry.h
gradient-drag.h
graphlayout.h
@@ -333,16 +325,14 @@ set(inkscape_SRC
helper-fns.h
icon-size.h
id-clash.h
- # ige-mac-menu.h
inkscape-version.h
inkscape.h
- interface.h
isinf.h
knot-enums.h
knot-holder-entity.h
+ knot-ptr.h
knot.h
knotholder.h
- knot-ptr.h
layer-fns.h
layer-manager.h
layer-model.h
@@ -351,7 +341,6 @@ set(inkscape_SRC
macros.h
main-cmdlineact.h
marker-test.h
- marker.h
media.h
menus-skeleton.h
message-context.h
@@ -376,7 +365,6 @@ set(inkscape_SRC
profile-manager.h
proj_pt.h
rdf.h
- registrytool.h
remove-last.h
removeoverlap.h
require-config.h
@@ -403,10 +391,10 @@ set(inkscape_SRC
splivarot.h
streq.h
strneq.h
- style-test.h
- style.h
style-enums.h
style-internal.h
+ style-test.h
+ style.h
svg-profile.h
svg-view-widget.h
svg-view.h
@@ -430,8 +418,10 @@ set(inkscape_SRC
if(WIN32)
list(APPEND inkscape_SRC
+ inkscape.rc
registrytool.cpp
#deptool.cpp
+ winconsole.cpp
winmain.cpp
)
endif()
@@ -471,7 +461,6 @@ list(APPEND inkscape_SRC
# All folders for internal inkscape
# these call add_inkscape_source
add_subdirectory(debug)
-add_subdirectory(dialogs)
add_subdirectory(display)
add_subdirectory(extension)
add_subdirectory(filters)
@@ -545,6 +534,8 @@ target_link_libraries(inkscape
uemf_LIB
2geom_LIB
depixelize_LIB
+ util_LIB
+ gc_LIB
${INKSCAPE_LIBS}
)
@@ -553,4 +544,3 @@ target_link_libraries(inkscape
# make executable for INKVIEW
#add_executable(inkview inkview.cpp)
# ...
-
diff --git a/src/document.cpp b/src/document.cpp
index 62e2f5b46..1c6bb76de 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -764,6 +764,17 @@ void SPDocument::setHeight(const Inkscape::Util::Quantity &height, bool changeSi
root->updateRepr();
}
+Geom::Rect SPDocument::getViewBox() const
+{
+ Geom::Rect viewBox;
+ if (root->viewBox_set) {
+ viewBox = root->viewBox;
+ } else {
+ viewBox = Geom::Rect::from_xywh( 0, 0, getWidth().value("px"), getHeight().value("px"));
+ }
+ return viewBox;
+}
+
void SPDocument::setViewBox(const Geom::Rect &viewBox)
{
root->viewBox_set = true;
diff --git a/src/document.h b/src/document.h
index ed19d123b..74dcfa75e 100644
--- a/src/document.h
+++ b/src/document.h
@@ -247,6 +247,7 @@ public:
Geom::Scale getDocumentScale() const;
Inkscape::Util::Quantity getWidth() const;
Inkscape::Util::Quantity getHeight() const;
+ Geom::Rect getViewBox() const;
Geom::Point getDimensions() const;
Geom::OptRect preferredBounds() const;
void setWidthAndHeight(const Inkscape::Util::Quantity &width, const Inkscape::Util::Quantity &height, bool changeSize=true);
diff --git a/src/helper/CMakeLists.txt b/src/helper/CMakeLists.txt
index 74ce2c85d..ff4760c24 100644
--- a/src/helper/CMakeLists.txt
+++ b/src/helper/CMakeLists.txt
@@ -13,6 +13,7 @@ set(helper_SRC
action-context.cpp
geom.cpp
geom-nodetype.cpp
+ geom-pathstroke.cpp
gnome-utils.cpp
pixbuf-ops.cpp
png-write.cpp
@@ -30,6 +31,7 @@ set(helper_SRC
action-context.h
geom-curves.h
geom-nodetype.h
+ geom-pathstroke.h
geom.h
gnome-utils.h
mathfns.h
diff --git a/src/helper/Makefile_insert b/src/helper/Makefile_insert
index 5cb4cea8d..e59fcfb70 100644
--- a/src/helper/Makefile_insert
+++ b/src/helper/Makefile_insert
@@ -12,6 +12,8 @@ ink_common_sources += \
helper/geom-curves.h \
helper/geom-nodetype.cpp \
helper/geom-nodetype.h \
+ helper/geom-pathstroke.cpp \
+ helper/geom-pathstroke.h \
helper/gnome-utils.cpp \
helper/gnome-utils.h \
helper/mathfns.h \
diff --git a/src/helper/geom-pathstroke.cpp b/src/helper/geom-pathstroke.cpp
new file mode 100644
index 000000000..eb0c432c6
--- /dev/null
+++ b/src/helper/geom-pathstroke.cpp
@@ -0,0 +1,770 @@
+/* Author:
+ * Liam P. White
+ *
+ * Copyright (C) 2014-2015 Author
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <iomanip>
+#include <2geom/path-sink.h>
+#include <2geom/point.h>
+#include <2geom/bezier-curve.h>
+#include <2geom/svg-elliptical-arc.h>
+#include <2geom/sbasis-to-bezier.h> // cubicbezierpath_from_sbasis
+#include <2geom/path-intersection.h>
+
+#include "helper/geom-pathstroke.h"
+
+namespace Geom {
+// 2geom/circle-circle.cpp, no header
+int circle_circle_intersection(Point X0, double r0, Point X1, double r1, Point &p0, Point &p1);
+
+/**
+ * Determine the intersection points between a circle C0 and a line defined
+ * by two points, X0 and X1.
+ *
+ * Which intersection point is assigned to p0 or p1 is unspecified, and callers
+ * should not depend on any particular intersection always being assigned to p0.
+ *
+ * Returns:
+ * If the line and circle do not cross, 0 is returned.
+ * If solution(s) exist, 2 is returned, and the results are written to p0 and p1.
+ */
+static int circle_line_intersection(Circle C0, Point X0, Point X1, Point &p0, Point &p1)
+{
+ /* equation of a circle: (x - h)^2 + (y - k)^2 = r^2 */
+ Coord r = C0.ray();
+ Coord h = C0.center()[X];
+ Coord k = C0.center()[Y];
+
+ Coord x0, y0;
+ Coord x1, y1;
+
+ if (are_near(X1[X], X0[X])) {
+ /* slope is undefined (vertical line) */
+ Coord c = X0[X];
+ Coord det = r*r - (c-h)*(c-h);
+
+ /* no intersection */
+ if (det < 0)
+ return 0;
+
+ /* solve for y */
+ y0 = k + std::sqrt(det);
+ y1 = k - std::sqrt(det);
+
+ // x == c (always)
+ x0 = c;
+ x1 = c;
+ } else {
+ /* equation of a line: y = mx + b */
+ Coord m = (X1[Y] - X0[Y]) / (X1[X] - X0[X]);
+ Coord b = X0[Y] - m*X0[X];
+
+ /* obtain quadratic for x: */
+ Coord A = m*m + 1;
+ Coord B = 2*h - 2*b*m + 2*k*m;
+ Coord C = b*b + h*h + k*k - r*r - 2*b*k;
+
+ Coord det = B*B - 4*A*C;
+
+ /* no intersection, circle and line do not cross */
+ if (det < 0)
+ return 0;
+
+ /* solve quadratic */
+ x0 = (B + std::sqrt(det)) / (2*A);
+ x1 = (B - std::sqrt(det)) / (2*A);
+
+ /* substitute the calculated x times to determine the y values */
+ y0 = m*x0 + b;
+ y1 = m*x1 + b;
+ }
+
+ p0 = Point(x0, y0);
+ p1 = Point(x1, y1);
+
+ return 2;
+}
+
+static Point intersection_point(Point origin_a, Point vector_a, Point origin_b, Point vector_b)
+{
+ Coord denom = cross(vector_b, vector_a);
+ if (!are_near(denom,0.)) {
+ Coord t = (cross(origin_a,vector_b) + cross(vector_b,origin_b)) / denom;
+ return origin_a + vector_a*t;
+ }
+ return Point(infinity(), infinity());
+}
+
+/**
+* Find circle that touches inside of the curve, with radius matching the curvature, at time value \c t.
+* Because this method internally uses unitTangentAt, t should be smaller than 1.0 (see unitTangentAt).
+*/
+static Circle touching_circle( D2<SBasis> const &curve, double t, double tol=0.01 )
+{
+ D2<SBasis> dM=derivative(curve);
+ if ( are_near(L2sq(dM(t)),0.) ) {
+ dM=derivative(dM);
+ }
+ if ( are_near(L2sq(dM(t)),0.) ) { // try second time
+ dM=derivative(dM);
+ }
+ Piecewise<D2<SBasis> > unitv = unitVector(dM,tol);
+ Piecewise<SBasis> dMlength = dot(Piecewise<D2<SBasis> >(dM),unitv);
+ Piecewise<SBasis> k = cross(derivative(unitv),unitv);
+ k = divide(k,dMlength,tol,3);
+ double curv = k(t); // note that this value is signed
+
+ Geom::Point normal = unitTangentAt(curve, t).cw();
+ double radius = 1/curv;
+ Geom::Point center = curve(t) + radius*normal;
+ return Geom::Circle(center, fabs(radius));
+}
+
+}
+
+namespace {
+
+// Join functions may:
+// - inspect any curve of the current path
+// - append any type of curve to the current path
+// - inspect the outgoing path
+//
+// Join functions must:
+// - append the outgoing curve
+// OR
+// - end at outgoing.finalPoint
+
+typedef void join_func(Geom::Path& res, Geom::Curve const& outgoing, double miter, double width);
+
+void bevel_join(Geom::Path& res, Geom::Curve const& outgoing, double /*miter*/, double /*width*/)
+{
+ res.appendNew<Geom::LineSegment>(outgoing.initialPoint());
+ res.append(outgoing);
+}
+
+void round_join(Geom::Path& res, Geom::Curve const& outgoing, double /*miter*/, double width)
+{
+ res.appendNew<Geom::SVGEllipticalArc>(width, width, 0, false, width <= 0, outgoing.initialPoint());
+ res.append(outgoing);
+}
+
+void miter_join_internal(Geom::Path& res, Geom::Curve const& outgoing, double miter, double width, bool clip)
+{
+ Geom::Curve const& incoming = res.back();
+ Geom::Point tang1 = Geom::unitTangentAt(reverse(incoming.toSBasis()), 0.);
+ Geom::Point tang2 = outgoing.unitTangentAt(0);
+ Geom::Point p = Geom::intersection_point(incoming.finalPoint(), tang1, outgoing.initialPoint(), tang2);
+
+ bool satisfied = false;
+ bool inc_ls = res.back_open().degreesOfFreedom() <= 4;
+
+ if (p.isFinite()) {
+ // check size of miter
+ Geom::Point point_on_path = incoming.finalPoint() + Geom::rot90(tang1)*width;
+ satisfied = Geom::distance(p, point_on_path) <= miter * 2.0 * width;
+ if (satisfied) {
+ // miter OK, check to see if we can do a relocation
+ if (inc_ls) {
+ res.setFinal(p);
+ } else {
+ res.appendNew<Geom::LineSegment>(p);
+ }
+ } else if (clip) {
+ // miter needs clipping, find two points
+ Geom::Point bisector_versor = Geom::Line(point_on_path, p).versor();
+ Geom::Point point_limit = point_on_path + miter * 2.0 * width * bisector_versor;
+
+ Geom::Point p1 = Geom::intersection_point(incoming.finalPoint(), tang1, point_limit, bisector_versor.cw());
+ Geom::Point p2 = Geom::intersection_point(outgoing.initialPoint(), tang2, point_limit, bisector_versor.cw());
+
+ if (inc_ls) {
+ res.setFinal(p1);
+ } else {
+ res.appendNew<Geom::LineSegment>(p1);
+ }
+ res.appendNew<Geom::LineSegment>(p2);
+ }
+ }
+
+ res.appendNew<Geom::LineSegment>(outgoing.initialPoint());
+
+ // check if we can do another relocation
+ bool out_ls = outgoing.degreesOfFreedom() <= 4;
+
+ if ( (satisfied || clip) && out_ls) {
+ res.setFinal(outgoing.finalPoint());
+ } else {
+ res.append(outgoing);
+ }
+}
+
+void miter_join(Geom::Path& res, Geom::Curve const& outgoing, double miter, double width) {
+ miter_join_internal( res, outgoing, miter, width, false );
+}
+
+void miter_clip_join(Geom::Path& res, Geom::Curve const& outgoing, double miter, double width) {
+ miter_join_internal( res, outgoing, miter, width, true );
+}
+
+Geom::Point pick_solution(Geom::Point points[2], Geom::Point tang2, Geom::Point endPt)
+{
+ Geom::Point sol;
+ if ( dot(tang2,points[0]-endPt) > 0 ) {
+ // points[0] is bad, choose points[1]
+ sol = points[1];
+ } else if ( dot(tang2,points[1]-endPt) > 0 ) { // points[0] could be good, now check points[1]
+ // points[1] is bad, choose points[0]
+ sol = points[0];
+ } else {
+ // both points are good, choose nearest
+ sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ? points[0] : points[1];
+ }
+ return sol;
+}
+
+void extrapolate_join(Geom::Path& res, Geom::Curve const& outgoing, double miter, double width)
+{
+ using namespace Geom;
+
+ Geom::Curve const& incoming = res.back();
+ Geom::Point startPt = incoming.finalPoint();
+ Geom::Point endPt = outgoing.initialPoint();
+ Geom::Point tang1 = Geom::unitTangentAt(reverse(incoming.toSBasis()), 0.);
+ Geom::Point tang2 = outgoing.unitTangentAt(0);
+
+ Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(incoming.toSBasis()), 0.);
+ Geom::Circle circle2 = Geom::touching_circle(outgoing.toSBasis(), 0);
+
+ bool inc_ls = !circle1.center().isFinite();
+ bool out_ls = !circle2.center().isFinite();
+
+ Geom::Point points[2];
+
+ int solutions = 0;
+ Geom::EllipticalArc *arc1 = NULL;
+ Geom::EllipticalArc *arc2 = NULL;
+ Geom::Point sol;
+ Geom::Point p1;
+ Geom::Point p2;
+
+ if (!inc_ls && !out_ls) {
+ // Two circles
+ solutions = Geom::circle_circle_intersection(circle1.center(), circle1.ray(),
+ circle2.center(), circle2.ray(),
+ points[0], points[1]);
+ if (solutions == 2) {
+ sol = pick_solution(points, tang2, endPt);
+ arc1 = circle1.arc(startPt, 0.5*(startPt+sol), sol, true);
+ arc2 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true);
+ }
+ } else if (inc_ls && !out_ls) {
+ // Line and circle
+ solutions = Geom::circle_line_intersection(circle2, incoming.initialPoint(), incoming.finalPoint(), points[0], points[1]);
+
+ if (solutions == 2) {
+ sol = pick_solution(points, tang2, endPt);
+ arc2 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true);
+ }
+ } else if (!inc_ls && out_ls) {
+ // Circle and line
+ solutions = Geom::circle_line_intersection(circle1, outgoing.initialPoint(), outgoing.finalPoint(), points[0], points[1]);
+
+ if (solutions == 2) {
+ sol = pick_solution(points, tang2, endPt);
+ arc1 = circle1.arc(startPt, 0.5*(sol+startPt), sol, true);
+ }
+ }
+
+ if (solutions != 2)
+ // no solutions available, fall back to miter
+ return miter_clip_join(res, outgoing, miter, width);
+
+ // We have a solution, thus sol is defined.
+ p1 = sol;
+
+ // See if we need to clip. Miter length is measured along a circular arc that is tangent to the
+ // bisector of the incoming and out going angles and passes through the end point (sol) of the
+ // line join.
+
+ // Center of circle is intersection of a line orthogonal to bisector and a line bisecting
+ // a chord connecting the path end point (point_on_path) and the join end point (sol).
+ Geom::Point point_on_path = startPt + Geom::rot90(tang1)*width;
+ Geom::Line bisector = make_angle_bisector_line(startPt, point_on_path, endPt);
+ Geom::Line ortho = make_orthogonal_line(point_on_path, bisector);
+
+ Geom::LineSegment chord(point_on_path, sol);
+ Geom::Line bisector_chord = make_bisector_line(chord);
+
+ Geom::Line limit_line;
+ double miter_limit = 2.0 * width * miter;
+ bool clipped = false;
+
+ if (are_parallel(bisector_chord, ortho)) {
+ // No intersection (can happen if curvatures are equal but opposite)
+ if (Geom::distance(point_on_path, sol) > miter_limit) {
+ clipped = true;
+ Geom::Point limit_point = point_on_path + miter_limit * bisector.versor();
+ limit_line = make_parallel_line( limit_point, ortho );
+ }
+ } else {
+ Geom::Point center =
+ Geom::intersection_point( bisector_chord.pointAt(0), bisector_chord.versor(),
+ ortho.pointAt(0), ortho.versor() );
+ Geom::Coord radius = distance(center, point_on_path);
+ Geom::Circle circle_center(center, radius);
+
+ double limit_angle = miter_limit / radius;
+
+ Geom::Ray start_ray(center, point_on_path);
+ Geom::Ray end_ray(center, sol);
+ Geom::Line limit_line(center, 0); // Angle set below
+
+ if (Geom::cross(start_ray.versor(), end_ray.versor()) > 0) {
+ limit_line.setAngle(start_ray.angle() - limit_angle);
+ } else {
+ limit_line.setAngle(start_ray.angle() + limit_angle);
+ }
+
+ Geom::EllipticalArc *arc_center = circle_center.arc(point_on_path, 0.5*(point_on_path + sol), sol, true);
+ if (arc_center && arc_center->sweepAngle() > limit_angle) {
+ // We need to clip
+ clipped = true;
+
+ if (!inc_ls) {
+ // Incoming circular
+ solutions = Geom::circle_line_intersection(circle1, limit_line.pointAt(0), limit_line.pointAt(1), points[0], points[1]);
+
+ if (solutions == 2) {
+ p1 = pick_solution(points, tang2, endPt);
+ delete arc1;
+ arc1 = circle1.arc(startPt, 0.5*(p1+startPt), p1, true);
+ }
+ } else {
+ p1 = Geom::intersection_point(startPt, tang1, limit_line.pointAt(0), limit_line.versor());
+ }
+
+ if (!out_ls) {
+ // Outgoing circular
+ solutions = Geom::circle_line_intersection(circle2, limit_line.pointAt(0), limit_line.pointAt(1), points[0], points[1]);
+
+ if (solutions == 2) {
+ p2 = pick_solution(points, tang1, endPt);
+ delete arc2;
+ arc2 = circle2.arc(p2, 0.5*(p2+endPt), endPt, true);
+ }
+ } else {
+ p2 = Geom::intersection_point(endPt, tang2, limit_line.pointAt(0), limit_line.versor());
+ }
+ }
+ }
+
+ // Add initial
+ if (arc1) {
+ res.append(*arc1);
+ } else {
+ // Straight line segment: move last point
+ res.setFinal(p1);
+ }
+
+ if (clipped) {
+ res.appendNew<Geom::LineSegment>(p2);
+ }
+
+ // Add outgoing
+ if (arc2) {
+ res.append(*arc2);
+ res.append(outgoing);
+ } else {
+ // Straight line segment:
+ res.appendNew<Geom::LineSegment>(outgoing.finalPoint());
+ }
+
+ delete arc1;
+ delete arc2;
+}
+
+void join_inside(Geom::Path& res, Geom::Curve const& outgoing)
+{
+ Geom::Curve const& incoming = res.back_open();
+ Geom::Crossings cross = Geom::crossings(incoming, outgoing);
+
+ if (!cross.empty()) {
+ // yeah if we could avoid allocing that'd be great
+ Geom::Curve *d1 = incoming.portion(0., cross[0].ta);
+ res.erase_last();
+ res.append(*d1);
+ delete d1;
+
+ Geom::Curve *d2 = outgoing.portion(cross[0].tb, 1.);
+ res.setFinal(d2->initialPoint());
+ res.append(*d2);
+ delete d2;
+ } else {
+ res.appendNew<Geom::LineSegment>(outgoing.initialPoint());
+ res.append(outgoing);
+ }
+}
+
+bool decide(Geom::Curve const& incoming, Geom::Curve const& outgoing)
+{
+ Geom::Point tang1 = Geom::unitTangentAt(reverse(incoming.toSBasis()), 0.);
+ Geom::Point tang2 = outgoing.unitTangentAt(0.);
+ return (Geom::cross(tang1, tang2) < 0);
+}
+
+void outline_helper(Geom::Path& res, Geom::Path const& to_add, double width, bool on_outside, double miter, Inkscape::LineJoinType join)
+{
+ if (res.size() == 0 || to_add.size() == 0)
+ return;
+
+ Geom::Curve const& outgoing = to_add[0];
+ if (Geom::are_near(res.finalPoint(), outgoing.initialPoint())) {
+ // if the points are /that/ close, just ignore this one
+ res.setFinal(outgoing.initialPoint());
+ res.append(outgoing);
+ return;
+ }
+
+ if (on_outside) {
+ join_func *jf;
+ switch (join) {
+ case Inkscape::JOIN_BEVEL:
+ jf = &bevel_join;
+ break;
+ case Inkscape::JOIN_ROUND:
+ jf = &round_join;
+ break;
+ case Inkscape::JOIN_EXTRAPOLATE:
+ jf = &extrapolate_join;
+ break;
+ case Inkscape::JOIN_MITER_CLIP:
+ jf = &miter_clip_join;
+ break;
+ default:
+ jf = &miter_join;
+ }
+ jf(res, outgoing, miter, width);
+ } else {
+ join_inside(res, outgoing);
+ }
+}
+
+// Offsetting a line segment is mathematically stable and quick to do
+Geom::LineSegment offset_line(Geom::LineSegment const& l, double width)
+{
+ Geom::Point tang1 = Geom::rot90(l.unitTangentAt(0));
+ Geom::Point tang2 = Geom::rot90(unitTangentAt(reverse(l.toSBasis()), 0.));
+
+ Geom::Point start = l.initialPoint() + tang1 * width;
+ Geom::Point end = l.finalPoint() - tang2 * width;
+
+ return Geom::LineSegment(start, end);
+}
+
+void get_cubic_data(Geom::CubicBezier const& bez, double time, double& len, double& rad)
+{
+ // get derivatives
+ std::vector<Geom::Point> derivs = bez.pointAndDerivatives(time, 3);
+
+ Geom::Point der1 = derivs[1]; // first deriv (tangent vector)
+ Geom::Point der2 = derivs[2]; // second deriv (tangent's tangent)
+ double l = Geom::L2(der1); // length
+
+ len = rad = 0;
+
+ // TODO: we might want to consider using Geom::touching_circle to determine the
+ // curvature radius here. Less code duplication, but slower
+
+ if (Geom::are_near(l, 0, 1e-4)) {
+ l = Geom::L2(der2);
+ Geom::Point der3 = derivs.at(3); // try second time
+ if (Geom::are_near(l, 0, 1e-4)) {
+ l = Geom::L2(der3);
+ if (Geom::are_near(l, 0)) {
+ return; // this isn't a segment...
+ }
+ rad = 1e8;
+ } else {
+ rad = -l * (Geom::dot(der2, der2) / Geom::cross(der3, der2));
+ }
+ } else {
+ rad = -l * (Geom::dot(der1, der1) / Geom::cross(der2, der1));
+ }
+ len = l;
+}
+
+void offset_cubic(Geom::Path& p, Geom::CubicBezier const& bez, double width, double tol, size_t levels)
+{
+ using Geom::X;
+ using Geom::Y;
+
+ Geom::Point start_pos = bez.initialPoint();
+ Geom::Point end_pos = bez.finalPoint();
+
+ Geom::Point start_normal = Geom::rot90(bez.unitTangentAt(0));
+ Geom::Point end_normal = -Geom::rot90(Geom::unitTangentAt(Geom::reverse(bez.toSBasis()), 0.));
+
+ // offset the start and end control points out by the width
+ Geom::Point start_new = start_pos + start_normal*width;
+ Geom::Point end_new = end_pos + end_normal*width;
+
+ // --------
+ double start_rad, end_rad;
+ double start_len, end_len; // tangent lengths
+ get_cubic_data(bez, 0, start_len, start_rad);
+ get_cubic_data(bez, 1, end_len, end_rad);
+
+ double start_off = 1, end_off = 1;
+ // correction of the lengths of the tangent to the offset
+ if (!Geom::are_near(start_rad, 0))
+ start_off += width / start_rad;
+ if (!Geom::are_near(end_rad, 0))
+ end_off += width / end_rad;
+ start_off *= start_len;
+ end_off *= end_len;
+ // --------
+
+ Geom::Point mid1_new = start_normal.ccw()*start_off;
+ mid1_new = Geom::Point(start_new[X] + mid1_new[X]/3., start_new[Y] + mid1_new[Y]/3.);
+ Geom::Point mid2_new = end_normal.ccw()*end_off;
+ mid2_new = Geom::Point(end_new[X] - mid2_new[X]/3., end_new[Y] - mid2_new[Y]/3.);
+
+ // create the estimate curve
+ Geom::CubicBezier c = Geom::CubicBezier(start_new, mid1_new, mid2_new, end_new);
+
+ // reached maximum recursive depth
+ // don't bother with any more correction
+ if (levels == 0) {
+ p.append(c, Geom::Path::STITCH_DISCONTINUOUS);
+ return;
+ }
+
+ // check the tolerance for our estimate to be a parallel curve
+ Geom::Point chk = c.pointAt(.5);
+ Geom::Point req = bez.pointAt(.5) + Geom::rot90(bez.unitTangentAt(.5))*width; // required accuracy
+
+ Geom::Point const diff = req - chk;
+ double const err = Geom::dot(diff, diff);
+
+ if (err < tol) {
+ if (Geom::are_near(start_new, p.finalPoint())) {
+ p.setFinal(start_new); // if it isn't near, we throw
+ }
+
+ // we're good, curve is accurate enough
+ p.append(c);
+ return;
+ } else {
+ // split the curve in two
+ std::pair<Geom::CubicBezier, Geom::CubicBezier> s = bez.subdivide(.5);
+ offset_cubic(p, s.first, width, tol, levels - 1);
+ offset_cubic(p, s.second, width, tol, levels - 1);
+ }
+}
+
+void offset_quadratic(Geom::Path& p, Geom::QuadraticBezier const& bez, double width, double tol, size_t levels)
+{
+ // cheat
+ // it's faster
+ // seriously
+ std::vector<Geom::Point> points = bez.points();
+ Geom::Point b1 = points[0] + (2./3) * (points[1] - points[0]);
+ Geom::Point b2 = b1 + (1./3) * (points[2] - points[0]);
+ Geom::CubicBezier cub = Geom::CubicBezier(points[0], b1, b2, points[2]);
+ offset_cubic(p, cub, width, tol, levels);
+}
+
+void offset_curve(Geom::Path& res, Geom::Curve const* current, double width)
+{
+ double const tolerance = 0.005;
+ size_t levels = 8;
+
+ if (current->isDegenerate()) return; // don't do anything
+
+ // TODO: we can handle SVGEllipticalArc here as well, do that!
+
+ if (Geom::BezierCurve const *b = dynamic_cast<Geom::BezierCurve const*>(current)) {
+ size_t order = b->order();
+ switch (order) {
+ case 1:
+ res.append(offset_line(static_cast<Geom::LineSegment const&>(*current), width));
+ break;
+ case 2: {
+ Geom::QuadraticBezier const& q = static_cast<Geom::QuadraticBezier const&>(*current);
+ offset_quadratic(res, q, width, tolerance, levels);
+ break;
+ }
+ case 3: {
+ Geom::CubicBezier const& cb = static_cast<Geom::CubicBezier const&>(*current);
+ offset_cubic(res, cb, width, tolerance, levels);
+ break;
+ }
+ default: {
+ Geom::Path sbasis_path = Geom::cubicbezierpath_from_sbasis(current->toSBasis(), tolerance);
+ for (size_t i = 0; i < sbasis_path.size(); ++i)
+ offset_curve(res, &sbasis_path[i], width);
+ break;
+ }
+ }
+ } else {
+ Geom::Path sbasis_path = Geom::cubicbezierpath_from_sbasis(current->toSBasis(), 0.1);
+ for (size_t i = 0; i < sbasis_path.size(); ++i)
+ offset_curve(res, &sbasis_path[i], width);
+ }
+}
+
+typedef void cap_func(Geom::PathBuilder& res, Geom::Path const& with_dir, Geom::Path const& against_dir, double width);
+
+void flat_cap(Geom::PathBuilder& res, Geom::Path const&, Geom::Path const& against_dir, double)
+{
+ res.lineTo(against_dir.initialPoint());
+}
+
+void round_cap(Geom::PathBuilder& res, Geom::Path const&, Geom::Path const& against_dir, double width)
+{
+ res.arcTo(width / 2., width / 2., 0., true, false, against_dir.initialPoint());
+}
+
+void square_cap(Geom::PathBuilder& res, Geom::Path const& with_dir, Geom::Path const& against_dir, double width)
+{
+ width /= 2.;
+ Geom::Point normal_1 = -Geom::unitTangentAt(Geom::reverse(with_dir.back().toSBasis()), 0.);
+ Geom::Point normal_2 = -against_dir[0].unitTangentAt(0.);
+ res.lineTo(with_dir.finalPoint() + normal_1*width);
+ res.lineTo(against_dir.initialPoint() + normal_2*width);
+ res.lineTo(against_dir.initialPoint());
+}
+
+void peak_cap(Geom::PathBuilder& res, Geom::Path const& with_dir, Geom::Path const& against_dir, double width)
+{
+ width /= 2.;
+ Geom::Point normal_1 = -Geom::unitTangentAt(Geom::reverse(with_dir.back().toSBasis()), 0.);
+ Geom::Point normal_2 = -against_dir[0].unitTangentAt(0.);
+ Geom::Point midpoint = ((with_dir.finalPoint() + normal_1*width) + (against_dir.initialPoint() + normal_2*width)) * 0.5;
+ res.lineTo(midpoint);
+ res.lineTo(against_dir.initialPoint());
+}
+
+} // namespace
+
+namespace Inkscape {
+
+Geom::PathVector outline(Geom::Path const& input, double width, double miter, LineJoinType join, LineCapType butt)
+{
+ if (input.size() == 0) return Geom::PathVector(); // nope, don't even try
+
+ Geom::PathBuilder res;
+ Geom::Path with_dir = half_outline(input, width/2., miter, join);
+ Geom::Path against_dir = half_outline(input.reverse(), width/2., miter, join);
+
+ res.moveTo(with_dir[0].initialPoint());
+ res.append(with_dir);
+
+ cap_func *cf;
+ switch (butt) {
+ case BUTT_ROUND:
+ cf = &round_cap;
+ break;
+ case BUTT_SQUARE:
+ cf = &square_cap;
+ break;
+ case BUTT_PEAK:
+ cf = &peak_cap;
+ break;
+ default:
+ cf = &flat_cap;
+ }
+
+ // glue caps
+ if (!input.closed()) {
+ cf(res, with_dir, against_dir, width);
+ } else {
+ res.closePath();
+ res.moveTo(against_dir.initialPoint());
+ }
+
+ res.append(against_dir);
+
+ if (!input.closed()) {
+ cf(res, against_dir, with_dir, width);
+ }
+
+ res.closePath();
+ res.flush();
+ return res.peek();
+}
+
+Geom::Path half_outline(Geom::Path const& input, double width, double miter, LineJoinType join)
+{
+ Geom::Path res;
+ if (input.size() == 0) return res;
+
+ Geom::Point tang1 = input[0].unitTangentAt(0);
+ Geom::Point start = input.initialPoint() + tang1 * width;
+ Geom::Path temp;
+
+ res.start(start);
+
+ // Do two curves at a time for efficiency, since the join function needs to know the outgoing curve as well
+ const size_t k = (input.back_closed().isDegenerate() && input.closed())
+ ?input.size_default()-1:input.size_default();
+ for (size_t u = 0; u < k; u += 2) {
+ temp = Geom::Path();
+
+ offset_curve(temp, &input[u], width);
+
+ // on the first run through, there isn't a join
+ if (u == 0) {
+ res.append(temp);
+ } else {
+ bool on_outside = decide(input[u-1], input[u]);
+ outline_helper(res, temp, width, on_outside, miter, join);
+ if (temp.size() > 0)
+ res.insert(res.end(), ++temp.begin(), temp.end());
+ }
+
+ // odd number of paths
+ if (u < k - 1) {
+ temp = Geom::Path();
+ offset_curve(temp, &input[u+1], width);
+ bool on_outside = decide(input[u], input[u+1]);
+ outline_helper(res, temp, width, on_outside, miter, join);
+ if (temp.size() > 0)
+ res.insert(res.end(), ++temp.begin(), temp.end());
+ }
+ }
+
+ if (input.closed()) {
+ Geom::Curve const &c1 = res.back();
+ Geom::Curve const &c2 = res.front();
+ temp = Geom::Path();
+ temp.append(c1);
+ Geom::Path temp2;
+ temp2.append(c2);
+ bool on_outside = decide(input.back(), input.front());
+ outline_helper(temp, temp2, width, on_outside, miter, join);
+ res.erase(res.begin());
+ res.erase_last();
+ //
+ res.append(temp);
+ res.close();
+ }
+
+ return res;
+}
+
+} // namespace Inkscape
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8 :
diff --git a/src/helper/geom-pathstroke.h b/src/helper/geom-pathstroke.h
new file mode 100644
index 000000000..0cfb9f817
--- /dev/null
+++ b/src/helper/geom-pathstroke.h
@@ -0,0 +1,58 @@
+#ifndef INKSCAPE_HELPER_PATH_STROKE_H
+#define INKSCAPE_HELPER_PATH_STROKE_H
+
+/* Author:
+ * Liam P. White
+ *
+ * Copyright (C) 2014-2015 Author
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <2geom/path.h>
+#include <2geom/pathvector.h>
+
+namespace Inkscape {
+
+enum LineJoinType {
+ JOIN_BEVEL,
+ JOIN_ROUND,
+ JOIN_MITER,
+ JOIN_MITER_CLIP,
+ JOIN_EXTRAPOLATE,
+};
+
+enum LineCapType {
+ BUTT_FLAT,
+ BUTT_ROUND,
+ BUTT_SQUARE,
+ BUTT_PEAK, // ?
+};
+
+/**
+ * Offset the input path by @a width.
+ * Joins may behave oddly if the width is negative.
+ *
+ * @param input
+ * @param width Amount to offset.
+ * @param miter Miter limit. Only used with JOIN_MITER, JOIN_MITER_CLIP, and JOIN_EXTRAPOLATE.
+ * @param join
+ */
+Geom::Path half_outline(Geom::Path const& input, double width, double miter, LineJoinType join = JOIN_BEVEL);
+
+Geom::PathVector outline(Geom::Path const& input, double width, double miter, LineJoinType join = JOIN_BEVEL, LineCapType cap = BUTT_FLAT);
+
+} // namespace Inkscape
+
+#endif // INKSCAPE_HELPER_PATH_STROKE_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/inkgc/CMakeLists.txt b/src/inkgc/CMakeLists.txt
index 22dd464e1..a4b96d5ee 100644
--- a/src/inkgc/CMakeLists.txt
+++ b/src/inkgc/CMakeLists.txt
@@ -1,11 +1,10 @@
-
set(libgc_SRC
gc.cpp
-
+
# -------
# Headers
gc-alloc.h
- gc-anchored.h
+ ../gc-anchored.h
gc-core.h
gc-managed.h
gc-soft-ptr.h
diff --git a/src/livarot/ShapeMisc.cpp b/src/livarot/ShapeMisc.cpp
index c0bfe9428..4f63007e7 100644
--- a/src/livarot/ShapeMisc.cpp
+++ b/src/livarot/ShapeMisc.cpp
@@ -371,9 +371,9 @@ Shape::ConvertToFormeNested (Path * dest, int nbP, Path * *orig, int /*wildPath*
int searchInd = 0;
int lastPtUsed = 0;
+ int parentContour=-1;
do
{
- int parentContour=-1;
int childEdge = -1;
bool foundChild = false;
int startBord = -1;
@@ -389,8 +389,10 @@ Shape::ConvertToFormeNested (Path * dest, int nbP, Path * *orig, int /*wildPath*
if (askTo < 0 || askTo >= numberOfEdges() ) {
parentContour=-1;
} else {
- parentContour = GPOINTER_TO_INT(swdData[askTo].misc);
- parentContour-=1; // pour compenser le decalage
+ if (getEdge(askTo).prevS >= 0) {
+ parentContour = GPOINTER_TO_INT(swdData[askTo].misc);
+ parentContour-=1; // pour compenser le decalage
+ }
childEdge = getPoint(fi).incidentEdge[FIRST];
}
}
diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt
index c8a02c810..c4b92e579 100644
--- a/src/live_effects/CMakeLists.txt
+++ b/src/live_effects/CMakeLists.txt
@@ -1,4 +1,3 @@
-
set(live_effects_SRC
effect.cpp
lpe-angle_bisector.cpp
@@ -6,6 +5,7 @@ set(live_effects_SRC
lpe-bendpath.cpp
lpe-boolops.cpp
lpe-bounding-box.cpp
+ lpe-bspline.cpp
lpe-circle_3pts.cpp
lpe-circle_with_radius.cpp
lpe-clone-original.cpp
@@ -13,7 +13,7 @@ set(live_effects_SRC
lpe-copy_rotate.cpp
lpe-curvestitch.cpp
lpe-dynastroke.cpp
- lpe-ellipse-5pts.cpp
+ lpe-ellipse_5pts.cpp
lpe-envelope.cpp
lpe-extrude.cpp
lpe-fill-between-many.cpp
@@ -21,8 +21,11 @@ set(live_effects_SRC
lpe-fillet-chamfer.cpp
lpe-gears.cpp
lpe-interpolate.cpp
+ lpe-interpolate_points.cpp
+ lpe-jointype.cpp
lpe-knot.cpp
lpe-lattice.cpp
+ lpe-lattice2.cpp
lpe-line_segment.cpp
lpe-mirror_symmetry.cpp
lpe-offset.cpp
@@ -30,43 +33,43 @@ set(live_effects_SRC
lpe-path_length.cpp
lpe-patternalongpath.cpp
lpe-perp_bisector.cpp
- lpe-perspective_path.cpp
lpe-perspective-envelope.cpp
+ lpe-perspective_path.cpp
lpe-powerstroke.cpp
lpe-recursiveskeleton.cpp
lpe-rough-hatches.cpp
+ lpe-roughen.cpp
lpe-ruler.cpp
lpe-show_handles.cpp
lpe-simplify.cpp
- # lpe-skeleton.cpp
+ lpe-skeleton.cpp
lpe-sketch.cpp
lpe-spiro.cpp
- lpe-roughen.cpp
lpe-tangent_to_curve.cpp
+ lpe-taperstroke.cpp
lpe-test-doEffect-stack.cpp
- lpe-bspline.cpp
lpe-text_label.cpp
- lpe-vonkoch.cpp
lpegroupbbox.cpp
lpeobject-reference.cpp
+ lpe-vonkoch.cpp
lpeobject.cpp
- spiro.cpp
spiro-converters.cpp
+ spiro.cpp
parameter/array.cpp
parameter/bool.cpp
parameter/filletchamferpointarray.cpp
- parameter/parameter.cpp
- parameter/path.cpp
parameter/originalpath.cpp
parameter/originalpatharray.cpp
+ parameter/parameter.cpp
parameter/path-reference.cpp
+ parameter/path.cpp
parameter/point.cpp
parameter/powerstrokepointarray.cpp
parameter/random.cpp
parameter/text.cpp
- paramter/transformedpoint.cpp
parameter/togglebutton.cpp
+ parameter/transformedpoint.cpp
parameter/unit.cpp
parameter/vector.cpp
@@ -80,6 +83,7 @@ set(live_effects_SRC
lpe-bendpath.h
lpe-boolops.h
lpe-bounding-box.h
+ lpe-bspline.h
lpe-circle_3pts.h
lpe-circle_with_radius.h
lpe-clone-original.h
@@ -87,7 +91,7 @@ set(live_effects_SRC
lpe-copy_rotate.h
lpe-curvestitch.h
lpe-dynastroke.h
- lpe-ellipse-5pts.h
+ lpe-ellipse_5pts.h
lpe-envelope.h
lpe-extrude.h
lpe-fill-between-many.h
@@ -95,8 +99,11 @@ set(live_effects_SRC
lpe-fillet-chamfer.h
lpe-gears.h
lpe-interpolate.h
+ lpe-interpolate_points.h
+ lpe-jointype.h
lpe-knot.h
lpe-lattice.h
+ lpe-lattice2.h
lpe-line_segment.h
lpe-mirror_symmetry.h
lpe-offset.h
@@ -104,47 +111,47 @@ set(live_effects_SRC
lpe-path_length.h
lpe-patternalongpath.h
lpe-perp_bisector.h
- lpe-perspective_path.h
lpe-perspective-envelope.h
- lpe-powerstroke.h
+ lpe-perspective_path.h
lpe-powerstroke-interpolators.h
+ lpe-powerstroke.h
lpe-recursiveskeleton.h
lpe-rough-hatches.h
+ lpe-roughen.h
lpe-ruler.h
- lpe-simplify.h
lpe-show_handles.h
+ lpe-simplify.h
lpe-skeleton.h
lpe-sketch.h
lpe-spiro.h
- lpe-roughen.h
lpe-tangent_to_curve.h
+ lpe-taperstroke.h
lpe-test-doEffect-stack.h
- lpe-bspline.h
lpe-text_label.h
lpe-vonkoch.h
lpegroupbbox.h
lpeobject-reference.h
lpeobject.h
- spiro.h
spiro-converters.h
+ spiro.h
parameter/array.h
parameter/bool.h
- parameter/filletchamferpointarray.h
parameter/enum.h
+ parameter/filletchamferpointarray.h
+ parameter/originalpath.h
+ parameter/originalpatharray.h
parameter/parameter.h
parameter/path-reference.h
parameter/path.h
- parameter/originalpath.h
- parameter/originalpatharray.h
parameter/point.h
parameter/powerstrokepointarray.h
parameter/random.h
parameter/text.h
parameter/togglebutton.h
+ parameter/transformedpoint.h
parameter/unit.h
parameter/vector.h
-
)
# add_inkscape_lib(live_effects_LIB "${live_effects_SRC}")
diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert
index 8f0a3ac57..dace45739 100644
--- a/src/live_effects/Makefile_insert
+++ b/src/live_effects/Makefile_insert
@@ -109,8 +109,6 @@ ink_common_sources += \
live_effects/lpe-fill-between-many.h \
live_effects/lpe-ellipse_5pts.cpp \
live_effects/lpe-ellipse_5pts.h \
- live_effects/pathoutlineprovider.cpp \
- live_effects/pathoutlineprovider.h \
live_effects/lpe-jointype.cpp \
live_effects/lpe-jointype.h \
live_effects/lpe-taperstroke.cpp \
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index b924d8a23..5d5a6e616 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -1,48 +1,16 @@
/*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <gtkmm.h>
-
-#if WITH_GLIBMM_2_32
-# include <glibmm/threads.h>
-#endif
-
-#include <glib.h>
-#include <glibmm/i18n.h>
-
-
-#include "display/curve.h"
-#include <2geom/bezier-curve.h>
-#include <2geom/point.h>
-#include "helper/geom-curves.h"
#include "live_effects/lpe-bspline.h"
-#include "live_effects/lpeobject.h"
-#include "live_effects/parameter/parameter.h"
#include "ui/widget/scalar.h"
-#include "xml/repr.h"
-#include "svg/svg.h"
+#include "display/curve.h"
+#include "helper/geom-curves.h"
#include "sp-path.h"
-#include "style.h"
-#include "document-private.h"
-#include "document.h"
-#include "document-undo.h"
-#include "verbs.h"
-#include "sp-lpe-item.h"
-#include "sp-namedview.h"
-#include "display/sp-canvas.h"
-#include <typeinfo>
-#include <vector>
-#include "util/units.h"
-// For handling un-continuous paths:
-#include "message-stack.h"
-#include "inkscape.h"
-
-using Inkscape::DocumentUndo;
+#include "svg/svg.h"
+#include "xml/repr.h"
+// TODO due to internal breakage in glibmm headers, this must be last:
+#include <glibmm/i18n.h>
namespace Inkscape {
namespace LivePathEffect {
@@ -106,13 +74,15 @@ void LPEBSpline::doEffect(SPCurve *curve)
}
// Make copy of old path as it is changed during processing
Geom::PathVector const original_pathv = curve->get_pathvector();
+
curve->reset();
for (Geom::PathVector::const_iterator path_it = original_pathv.begin();
path_it != original_pathv.end(); ++path_it) {
- if (path_it->empty())
+ if (path_it->empty()){
continue;
-
+ }
+ hp.push_back(*path_it);
Geom::Path::const_iterator curve_it1 = path_it->begin();
Geom::Path::const_iterator curve_it2 = ++(path_it->begin());
Geom::Path::const_iterator curve_endit = path_it->end_default();
diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h
index 642562b24..8017e39ef 100644
--- a/src/live_effects/lpe-bspline.h
+++ b/src/live_effects/lpe-bspline.h
@@ -6,9 +6,8 @@
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-
#include "live_effects/effect.h"
-#include "live_effects/parameter/bool.h"
+
#include <vector>
namespace Inkscape {
diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp
index bf2526986..0111a0f99 100644
--- a/src/live_effects/lpe-jointype.cpp
+++ b/src/live_effects/lpe-jointype.cpp
@@ -8,7 +8,7 @@
*/
#include "live_effects/parameter/enum.h"
-#include "live_effects/pathoutlineprovider.h"
+#include "helper/geom-pathstroke.h"
#include "sp-shape.h"
#include "style.h"
@@ -28,19 +28,19 @@ namespace Inkscape {
namespace LivePathEffect {
static const Util::EnumData<unsigned> JoinTypeData[] = {
- {LINEJOIN_STRAIGHT, N_("Beveled"), "bevel"},
- {LINEJOIN_ROUND, N_("Rounded"), "round"},
- {LINEJOIN_POINTY, N_("Miter"), "miter"},
- {LINEJOIN_REFLECTED, N_("Reflected"), "extrapolated"},
- {LINEJOIN_EXTRAPOLATED, N_("Extrapolated arc"), "extrp_arc"}
+ {JOIN_BEVEL, N_("Beveled"), "bevel"},
+ {JOIN_ROUND, N_("Rounded"), "round"},
+ {JOIN_MITER, N_("Miter"), "miter"},
+ {JOIN_MITER_CLIP, N_("Miter Clip"), "miter-clip"},
+ {JOIN_EXTRAPOLATE, N_("Extrapolated arc"), "extrp_arc"},
};
static const Util::EnumData<unsigned> CapTypeData[] = {
- {BUTT_STRAIGHT, N_("Butt"), "butt"},
+ {BUTT_FLAT, N_("Butt"), "butt"},
{BUTT_ROUND, N_("Rounded"), "round"},
{BUTT_SQUARE, N_("Square"), "square"},
- {BUTT_POINTY, N_("Peak"), "peak"},
- {BUTT_LEANED, N_("Leaned"), "leaned"}
+ {BUTT_PEAK, N_("Peak"), "peak"},
+ //{BUTT_LEANED, N_("Leaned"), "leaned"}
};
static const Util::EnumDataConverter<unsigned> CapTypeConverter(CapTypeData, sizeof(CapTypeData)/sizeof(*CapTypeData));
@@ -50,9 +50,9 @@ LPEJoinType::LPEJoinType(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
line_width(_("Line width"), _("Thickness of the stroke"), "line_width", &wr, this, 1.),
linecap_type(_("Line cap"), _("The end shape of the stroke"), "linecap_type", CapTypeConverter, &wr, this, butt_straight),
- linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED),
- start_lean(_("Start path lean"), _("Start path lean"), "start_lean", &wr, this, 0.),
- end_lean(_("End path lean"), _("End path lean"), "end_lean", &wr, this, 0.),
+ linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", JoinTypeConverter, &wr, this, JOIN_EXTRAPOLATE),
+ //start_lean(_("Start path lean"), _("Start path lean"), "start_lean", &wr, this, 0.),
+ //end_lean(_("End path lean"), _("End path lean"), "end_lean", &wr, this, 0.),
miter_limit(_("Miter limit:"), _("Maximum length of the miter join (in units of stroke width)"), "miter_limit", &wr, this, 100.),
attempt_force_join(_("Force miter"), _("Overrides the miter limit and forces a join."), "attempt_force_join", &wr, this, true)
{
@@ -60,17 +60,16 @@ LPEJoinType::LPEJoinType(LivePathEffectObject *lpeobject) :
registerParameter(&linecap_type);
registerParameter(&line_width);
registerParameter(&linejoin_type);
- registerParameter(&start_lean);
- registerParameter(&end_lean);
+ //registerParameter(&start_lean);
+ //registerParameter(&end_lean);
registerParameter(&miter_limit);
registerParameter(&attempt_force_join);
- was_initialized = false;
- start_lean.param_set_range(-1,1);
- start_lean.param_set_increments(0.1, 0.1);
- start_lean.param_set_digits(4);
- end_lean.param_set_range(-1,1);
- end_lean.param_set_increments(0.1, 0.1);
- end_lean.param_set_digits(4);
+ //start_lean.param_set_range(-1,1);
+ //start_lean.param_set_increments(0.1, 0.1);
+ //start_lean.param_set_digits(4);
+ //end_lean.param_set_range(-1,1);
+ //end_lean.param_set_increments(0.1, 0.1);
+ //end_lean.param_set_digits(4);
}
LPEJoinType::~LPEJoinType()
@@ -87,38 +86,30 @@ void LPEJoinType::doOnApply(SPLPEItem const* lpeitem)
double width = (lpeitem && lpeitem->style) ? lpeitem->style->stroke_width.computed : 1.;
SPCSSAttr *css = sp_repr_css_attr_new ();
- if (true) {
- if (lpeitem->style->stroke.isPaintserver()) {
- SPPaintServer * server = lpeitem->style->getStrokePaintServer();
- if (server) {
- Glib::ustring str;
- str += "url(#";
- str += server->getId();
- str += ")";
- sp_repr_css_set_property (css, "fill", str.c_str());
- }
- } else if (lpeitem->style->stroke.isColor()) {
- gchar c[64];
- sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value)));
- sp_repr_css_set_property (css, "fill", c);
- } else {
- sp_repr_css_set_property (css, "fill", "none");
+ if (lpeitem->style->stroke.isPaintserver()) {
+ SPPaintServer * server = lpeitem->style->getStrokePaintServer();
+ if (server) {
+ Glib::ustring str;
+ str += "url(#";
+ str += server->getId();
+ str += ")";
+ sp_repr_css_set_property (css, "fill", str.c_str());
}
+ } else if (lpeitem->style->stroke.isColor()) {
+ gchar c[64];
+ sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value)));
+ sp_repr_css_set_property (css, "fill", c);
} else {
- sp_repr_css_unset_property (css, "fill");
+ sp_repr_css_set_property (css, "fill", "none");
}
+ sp_repr_css_set_property(css, "fill-rule", "nonzero");
sp_repr_css_set_property(css, "stroke", "none");
sp_desktop_apply_css_recursive(item, css, true);
sp_repr_css_attr_unref (css);
- if (!was_initialized)
- {
- was_initialized = true;
- line_width.param_set_value(width);
- }
- } else {
- g_warning("LPE Join Type can only be applied to paths (not groups).");
+
+ line_width.param_set_value(width);
}
}
@@ -126,30 +117,25 @@ void LPEJoinType::doOnApply(SPLPEItem const* lpeitem)
void LPEJoinType::doOnRemove(SPLPEItem const* lpeitem)
{
-
if (SP_IS_SHAPE(lpeitem)) {
SPLPEItem *item = const_cast<SPLPEItem*>(lpeitem);
SPCSSAttr *css = sp_repr_css_attr_new ();
- if (true) {
- if (lpeitem->style->fill.isPaintserver()) {
- SPPaintServer * server = lpeitem->style->getFillPaintServer();
- if (server) {
- Glib::ustring str;
- str += "url(#";
- str += server->getId();
- str += ")";
- sp_repr_css_set_property (css, "stroke", str.c_str());
- }
- } else if (lpeitem->style->fill.isColor()) {
- gchar c[64];
- sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value)));
- sp_repr_css_set_property (css, "stroke", c);
- } else {
- sp_repr_css_set_property (css, "stroke", "none");
+ if (lpeitem->style->fill.isPaintserver()) {
+ SPPaintServer * server = lpeitem->style->getFillPaintServer();
+ if (server) {
+ Glib::ustring str;
+ str += "url(#";
+ str += server->getId();
+ str += ")";
+ sp_repr_css_set_property (css, "stroke", str.c_str());
}
+ } else if (lpeitem->style->fill.isColor()) {
+ gchar c[64];
+ sp_svg_write_color (c, sizeof(c), lpeitem->style->fill.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->fill_opacity.value)));
+ sp_repr_css_set_property (css, "stroke", c);
} else {
- sp_repr_css_unset_property (css, "stroke");
+ sp_repr_css_set_property (css, "stroke", "none");
}
Inkscape::CSSOStringStream os;
@@ -164,15 +150,18 @@ void LPEJoinType::doOnRemove(SPLPEItem const* lpeitem)
}
}
-// NOTE: I originally had all the outliner functions defined in here, but they were actually useful
-// enough for other LPEs so I moved them all into pathoutlineprovider.cpp. The code here is just a
-// wrapper around it.
std::vector<Geom::Path> LPEJoinType::doEffect_path(std::vector<Geom::Path> const & path_in)
{
- return Outline::PathVectorOutline(path_in, line_width, static_cast<ButtTypeMod>(linecap_type.get_value()),
- static_cast<LineJoinType>(linejoin_type.get_value()),
- (attempt_force_join ? std::numeric_limits<double>::max() : miter_limit),
- start_lean/2 ,end_lean/2);
+ Geom::PathVector ret;
+ for (size_t i = 0; i < path_in.size(); ++i) {
+ Geom::PathVector tmp = Inkscape::outline(path_in[i], line_width,
+ (attempt_force_join ? std::numeric_limits<double>::max() : miter_limit),
+ static_cast<LineJoinType>(linejoin_type.get_value()),
+ static_cast<LineCapType>(linecap_type.get_value()));
+ ret.insert(ret.begin(), tmp.begin(), tmp.end());
+ }
+
+ return ret;
}
} // namespace LivePathEffect
diff --git a/src/live_effects/lpe-jointype.h b/src/live_effects/lpe-jointype.h
index 73705666d..bca0961c9 100644
--- a/src/live_effects/lpe-jointype.h
+++ b/src/live_effects/lpe-jointype.h
@@ -33,11 +33,10 @@ private:
ScalarParam line_width;
EnumParam<unsigned> linecap_type;
EnumParam<unsigned> linejoin_type;
- ScalarParam start_lean;
- ScalarParam end_lean;
+ //ScalarParam start_lean;
+ //ScalarParam end_lean;
ScalarParam miter_limit;
BoolParam attempt_force_join;
- bool was_initialized;
};
} //namespace LivePathEffect
diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp
index d60a13c23..b5885bdb3 100644
--- a/src/live_effects/lpe-perspective-envelope.cpp
+++ b/src/live_effects/lpe-perspective-envelope.cpp
@@ -48,11 +48,11 @@ LPEPerspectiveEnvelope::LPEPerspectiveEnvelope(LivePathEffectObject *lpeobject)
Down_Right_Point(_("Down Right"), _("Down Right - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "Down_Right_Point", &wr, this)
{
// register all your parameters here, so Inkscape knows which parameters this effect has:
- registerParameter( dynamic_cast<Parameter *>(&deform_type));
- registerParameter( dynamic_cast<Parameter *>(&Up_Left_Point) );
- registerParameter( dynamic_cast<Parameter *>(&Up_Right_Point) );
- registerParameter( dynamic_cast<Parameter *>(&Down_Left_Point) );
- registerParameter( dynamic_cast<Parameter *>(&Down_Right_Point) );
+ registerParameter(&deform_type);
+ registerParameter(&Up_Left_Point);
+ registerParameter(&Up_Right_Point);
+ registerParameter(&Down_Left_Point);
+ registerParameter(&Down_Right_Point);
}
LPEPerspectiveEnvelope::~LPEPerspectiveEnvelope()
@@ -340,8 +340,8 @@ LPEPerspectiveEnvelope::resetDefaults(SPItem const* item)
{
Effect::resetDefaults(item);
original_bbox(SP_LPE_ITEM(item));
- resetGrid();
setDefaults();
+ resetGrid();
}
void
diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp
index f7fe9592d..5d9d224e8 100644
--- a/src/live_effects/lpe-powerstroke.cpp
+++ b/src/live_effects/lpe-powerstroke.cpp
@@ -297,7 +297,8 @@ LPEPowerStroke::doOnApply(SPLPEItem const* lpeitem)
} else {
sp_repr_css_unset_property (css, "fill");
}
-
+
+ sp_repr_css_set_property(css, "fill-rule", "nonzero");
sp_repr_css_set_property(css, "stroke", "none");
sp_desktop_apply_css_recursive(item, css, true);
@@ -330,25 +331,21 @@ void LPEPowerStroke::doOnRemove(SPLPEItem const* lpeitem)
if (SP_IS_SHAPE(lpeitem)) {
SPLPEItem *item = const_cast<SPLPEItem*>(lpeitem);
SPCSSAttr *css = sp_repr_css_attr_new ();
- if (true) {
- if (lpeitem->style->fill.isPaintserver()) {
- SPPaintServer * server = lpeitem->style->getFillPaintServer();
- if (server) {
- Glib::ustring str;
- str += "url(#";
- str += server->getId();
- str += ")";
- sp_repr_css_set_property (css, "stroke", str.c_str());
- }
- } else if (lpeitem->style->fill.isColor()) {
- gchar c[64];
- sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value)));
- sp_repr_css_set_property (css, "stroke", c);
- } else {
- sp_repr_css_set_property (css, "stroke", "none");
+ if (lpeitem->style->fill.isPaintserver()) {
+ SPPaintServer * server = lpeitem->style->getFillPaintServer();
+ if (server) {
+ Glib::ustring str;
+ str += "url(#";
+ str += server->getId();
+ str += ")";
+ sp_repr_css_set_property (css, "stroke", str.c_str());
}
+ } else if (lpeitem->style->fill.isColor()) {
+ char c[64] = {0};
+ sp_svg_write_color (c, sizeof(c), lpeitem->style->fill.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->fill_opacity.value)));
+ sp_repr_css_set_property (css, "stroke", c);
} else {
- sp_repr_css_unset_property (css, "stroke");
+ sp_repr_css_set_property (css, "stroke", "none");
}
Inkscape::CSSOStringStream os;
diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp
index 7a024147c..2c74af6d6 100644
--- a/src/live_effects/lpe-taperstroke.cpp
+++ b/src/live_effects/lpe-taperstroke.cpp
@@ -19,7 +19,8 @@
#include <2geom/circle.h>
#include <2geom/sbasis-to-bezier.h>
-#include "pathoutlineprovider.h"
+#include "helper/geom-nodetype.h"
+#include "helper/geom-pathstroke.h"
#include "display/curve.h"
#include "sp-shape.h"
#include "style.h"
@@ -60,11 +61,10 @@ namespace TpS {
} // TpS
static const Util::EnumData<unsigned> JoinType[] = {
- {LINEJOIN_STRAIGHT, N_("Beveled"), "bevel"},
- {LINEJOIN_ROUND, N_("Rounded"), "round"},
- {LINEJOIN_REFLECTED, N_("Reflected"), "reflected"},
- {LINEJOIN_POINTY, N_("Miter"), "miter"},
- {LINEJOIN_EXTRAPOLATED, N_("Extrapolated"), "extrapolated"}
+ {JOIN_BEVEL, N_("Beveled"), "bevel"},
+ {JOIN_ROUND, N_("Rounded"), "round"},
+ {JOIN_MITER, N_("Miter"), "miter"},
+ {JOIN_EXTRAPOLATE, N_("Extrapolated"), "extrapolated"},
};
static const Util::EnumDataConverter<unsigned> JoinTypeConverter(JoinType, sizeof (JoinType)/sizeof(*JoinType));
@@ -75,7 +75,7 @@ LPETaperStroke::LPETaperStroke(LivePathEffectObject *lpeobject) :
attach_start(_("Start offset:"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2),
attach_end(_("End offset:"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2),
smoothing(_("Taper smoothing:"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.5),
- join_type(_("Join type:"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED),
+ join_type(_("Join type:"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, JOIN_EXTRAPOLATE),
miter_limit(_("Miter limit:"), _("Limit for miter joins"), "miter_limit", &wr, this, 100.)
{
show_orig_path = true;
@@ -102,27 +102,24 @@ void LPETaperStroke::doOnApply(SPLPEItem const* lpeitem)
double width = (lpeitem && lpeitem->style) ? lpeitem->style->stroke_width.computed : 1.;
SPCSSAttr *css = sp_repr_css_attr_new ();
- if (true) {
- if (lpeitem->style->stroke.isPaintserver()) {
- SPPaintServer * server = lpeitem->style->getStrokePaintServer();
- if (server) {
- Glib::ustring str;
- str += "url(#";
- str += server->getId();
- str += ")";
- sp_repr_css_set_property (css, "fill", str.c_str());
- }
- } else if (lpeitem->style->stroke.isColor()) {
- gchar c[64];
- sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value)));
- sp_repr_css_set_property (css, "fill", c);
- } else {
- sp_repr_css_set_property (css, "fill", "none");
+ if (lpeitem->style->stroke.isPaintserver()) {
+ SPPaintServer * server = lpeitem->style->getStrokePaintServer();
+ if (server) {
+ Glib::ustring str;
+ str += "url(#";
+ str += server->getId();
+ str += ")";
+ sp_repr_css_set_property (css, "fill", str.c_str());
}
+ } else if (lpeitem->style->stroke.isColor()) {
+ gchar c[64];
+ sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value)));
+ sp_repr_css_set_property (css, "fill", c);
} else {
- sp_repr_css_unset_property (css, "fill");
+ sp_repr_css_set_property (css, "fill", "none");
}
+ sp_repr_css_set_property(css, "fill-rule", "nonzero");
sp_repr_css_set_property(css, "stroke", "none");
sp_desktop_apply_css_recursive(item, css, true);
@@ -130,7 +127,7 @@ void LPETaperStroke::doOnApply(SPLPEItem const* lpeitem)
line_width.param_set_value(width);
} else {
- printf("WARNING: It only makes sense to apply Join Type to paths (not groups).\n");
+ printf("WARNING: It only makes sense to apply Taper stroke to paths (not groups).\n");
}
}
@@ -142,25 +139,21 @@ void LPETaperStroke::doOnRemove(SPLPEItem const* lpeitem)
SPLPEItem *item = const_cast<SPLPEItem*>(lpeitem);
SPCSSAttr *css = sp_repr_css_attr_new ();
- if (true) {
- if (lpeitem->style->fill.isPaintserver()) {
- SPPaintServer * server = lpeitem->style->getFillPaintServer();
- if (server) {
- Glib::ustring str;
- str += "url(#";
- str += server->getId();
- str += ")";
- sp_repr_css_set_property (css, "stroke", str.c_str());
- }
- } else if (lpeitem->style->fill.isColor()) {
- gchar c[64];
- sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value)));
- sp_repr_css_set_property (css, "stroke", c);
- } else {
- sp_repr_css_set_property (css, "stroke", "none");
+ if (lpeitem->style->fill.isPaintserver()) {
+ SPPaintServer * server = lpeitem->style->getFillPaintServer();
+ if (server) {
+ Glib::ustring str;
+ str += "url(#";
+ str += server->getId();
+ str += ")";
+ sp_repr_css_set_property (css, "stroke", str.c_str());
}
+ } else if (lpeitem->style->fill.isColor()) {
+ gchar c[64];
+ sp_svg_write_color (c, sizeof(c), lpeitem->style->fill.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->fill_opacity.value)));
+ sp_repr_css_set_property (css, "stroke", c);
} else {
- sp_repr_css_unset_property (css, "stroke");
+ sp_repr_css_set_property (css, "stroke", "none");
}
Inkscape::CSSOStringStream os;
@@ -179,15 +172,22 @@ using Geom::D2;
using Geom::SBasis;
// leave Geom::Path
-Geom::Path return_at_first_cusp(Geom::Path const & path_in, double /*smooth_tolerance*/ = 0.05) {
- return Geom::split_at_cusps(path_in)[0];
+static Geom::Path return_at_first_cusp(Geom::Path const & path_in, double /*smooth_tolerance*/ = 0.05)
+{
+ Geom::Path temp;
+
+ for (unsigned i = 0; i < path_in.size(); i++) {
+ temp.append(path_in[i]);
+ if (Geom::get_nodetype(path_in[i], path_in[i + 1]) != Geom::NODE_SMOOTH ) {
+ break;
+ }
+ }
+
+ return temp;
}
Piecewise<D2<SBasis> > stretch_along(Piecewise<D2<SBasis> > pwd2_in, Geom::Path pattern, double width);
-// references to pointers
-void subdivideCurve(Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second);
-
// actual effect
Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in)
@@ -285,7 +285,7 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in)
// although this seems obvious, it can probably lead to bugs.
if (!metInMiddle) {
// append the outside outline of the path (goes with the direction of the path)
- throwaway_path = Outline::PathOutsideOutline(pathv_out[1], -fabs(line_width), static_cast<LineJoinType>(join_type.get_value()), miter_limit);
+ throwaway_path = half_outline(pathv_out[1], fabs(line_width)/2., miter_limit, static_cast<LineJoinType>(join_type.get_value()));
if (!zeroStart && real_path.size() >= 1 && throwaway_path.size() >= 1) {
if (!Geom::are_near(real_path.finalPoint(), throwaway_path.initialPoint())) {
real_path.appendNew<Geom::LineSegment>(throwaway_path.initialPoint());
@@ -317,7 +317,7 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in)
if (!metInMiddle) {
// append the inside outline of the path (against direction)
- throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), -fabs(line_width), static_cast<LineJoinType>(join_type.get_value()), miter_limit);
+ throwaway_path = half_outline(pathv_out[1].reverse(), fabs(line_width)/2., miter_limit, static_cast<LineJoinType>(join_type.get_value()));
if (!Geom::are_near(real_path.finalPoint(), throwaway_path.initialPoint()) && real_path.size() >= 1) {
real_path.appendNew<Geom::LineSegment>(throwaway_path.initialPoint());
@@ -347,85 +347,18 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in)
*/
Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & path_in)
{
- size_t size = path_in[0].size();
-
- unsigned loc = (unsigned)attach_start;
- Geom::Curve * curve_start = path_in[0] [loc].duplicate();
-
- std::vector<Geom::Path> pathv_out;
- Geom::Path path_out = Geom::Path();
-
- Geom::Path trimmed_start = Geom::Path();
- Geom::Path trimmed_end = Geom::Path();
-
- for (size_t i = 0; i < loc; ++i) {
- trimmed_start.append(path_in[0] [i]);
- }
-
- Geom::Curve * temp;
- subdivideCurve(curve_start, attach_start - loc, temp, curve_start);
- trimmed_start.append(*temp);
- if (temp) delete temp; temp = 0;
-
- // special case: path is one segment long
- // special case: what if the two knots occupy the same segment?
- if ((size == 1) || ( size - unsigned(attach_end) - 1 == loc )) {
-
- // If you look into it, I don't actually think there is a working way to do this
- // with only point math. So we use nearest_point instead.
- Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_start);
-
- // it is just a dumb segment
- // we have to do some shifting here because the value changed when we reduced the length
- // of the previous segment.
-
- subdivideCurve(curve_start, t, curve_start, temp);
- trimmed_end.append(*temp);
- if (temp) delete temp; temp = 0;
-
- for (size_t j = (size - attach_end) + 1; j < size; ++j) {
- trimmed_end.append(path_in[0] [j]);
- }
+ Geom::Coord endTime = path_in[0].size() - attach_end;
- path_out.append(*curve_start);
- pathv_out.push_back(trimmed_start);
- pathv_out.push_back(path_out);
- pathv_out.push_back(trimmed_end);
- return pathv_out;
- }
-
- pathv_out.push_back(trimmed_start);
-
- // append almost all of the rest of the path, ignore the curves that the knot is past (we'll get to it in a minute)
- path_out.append(*curve_start);
-
- for (size_t k = loc + 1; k < (size - unsigned(attach_end)) - 1; ++k) {
- path_out.append(path_in[0] [k]);
- }
-
- // deal with the last segment in a very similar fashion to the first
- loc = size - attach_end;
-
- Geom::Curve * curve_end = path_in[0] [loc].duplicate();
-
- Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_end);
-
- subdivideCurve(curve_end, t, curve_end, temp);
- trimmed_end.append(*temp);
- if (temp) delete temp; temp = 0;
-
- for (size_t j = (size - attach_end) + 1; j < size; ++j) {
- trimmed_end.append(path_in[0] [j]);
- }
-
- path_out.append(*curve_end);
- pathv_out.push_back(path_out);
-
- pathv_out.push_back(trimmed_end);
-
- if (curve_end) delete curve_end;
- if (curve_start) delete curve_start;
- return pathv_out;
+ Geom::Path p1 = path_in[0].portion(0., attach_start);
+ Geom::Path p2 = path_in[0].portion(attach_start, endTime);
+ Geom::Path p3 = path_in[0].portion(endTime, path_in[0].size());
+
+ Geom::PathVector out;
+ out.push_back(p1);
+ out.push_back(p2);
+ out.push_back(p3);
+
+ return out;
}
@@ -513,23 +446,6 @@ Piecewise<D2<SBasis> > stretch_along(Piecewise<D2<SBasis> > pwd2_in, Geom::Path
}
}
-void subdivideCurve(Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second)
-{
- if (Geom::LineSegment* linear = dynamic_cast<Geom::LineSegment*>(curve_in)) {
- // special case for line segments
- std::pair<Geom::LineSegment, Geom::LineSegment> seg_pair = linear->subdivide(t);
- val_first = seg_pair.first.duplicate();
- val_second = seg_pair.second.duplicate();
- } else {
- // all other cases:
- Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(curve_in->toSBasis());
- std::pair<Geom::CubicBezier, Geom::CubicBezier> cubic_pair = cubic.subdivide(t);
- val_first = cubic_pair.first.duplicate();
- val_second = cubic_pair.second.duplicate();
- }
-}
-
-
void LPETaperStroke::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item)
{
KnotHolderEntity *e = new TpS::KnotHolderEntityAttachBegin(this);
diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp
deleted file mode 100644
index 21a0fb809..000000000
--- a/src/live_effects/pathoutlineprovider.cpp
+++ /dev/null
@@ -1,803 +0,0 @@
-/* Author:
- * Liam P. White <inkscapebrony@gmail.com>
- *
- * Copyright (C) 2014 Author
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <2geom/angle.h>
-#include <2geom/path.h>
-#include <2geom/circle.h>
-#include <2geom/sbasis-to-bezier.h>
-#include <2geom/shape.h>
-#include <2geom/transforms.h>
-#include <2geom/path-sink.h>
-#include <cstdio>
-
-#include "pathoutlineprovider.h"
-#include "livarot/path-description.h"
-#include "helper/geom-nodetype.h"
-#include "svg/svg.h"
-
-namespace Geom {
-/**
-* Refer to: Weisstein, Eric W. "Circle-Circle Intersection."
- From MathWorld--A Wolfram Web Resource.
- http://mathworld.wolfram.com/Circle-CircleIntersection.html
-*
-* @return 0 if no intersection
-* @return 1 if one circle is contained in the other
-* @return 2 if intersections are found (they are written to p0 and p1)
-*/
-static int circle_circle_intersection(Circle const &circle0, Circle const &circle1, Point & p0, Point & p1)
-{
- Point X0 = circle0.center();
- double r0 = circle0.ray();
- Point X1 = circle1.center();
- double r1 = circle1.ray();
-
- /* dx and dy are the vertical and horizontal distances between
- * the circle centers.
- */
- Point D = X1 - X0;
-
- /* Determine the straight-line distance between the centers. */
- double d = L2(D);
-
- /* Check for solvability. */
- if (d > (r0 + r1)) {
- /* no solution. circles do not intersect. */
- return 0;
- }
- if (d <= fabs(r0 - r1)) {
- /* no solution. one circle is contained in the other */
- return 1;
- }
-
- /* 'point 2' is the point where the line through the circle
- * intersection points crosses the line between the circle
- * centers.
- */
-
- /* Determine the distance from point 0 to point 2. */
- double a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ;
-
- /* Determine the coordinates of point 2. */
- Point p2 = X0 + D * (a/d);
-
- /* Determine the distance from point 2 to either of the
- * intersection points.
- */
- double h = std::sqrt((r0*r0) - (a*a));
-
- /* Now determine the offsets of the intersection points from
- * point 2.
- */
- Point r = (h/d)*rot90(D);
-
- /* Determine the absolute intersection points. */
- p0 = p2 + r;
- p1 = p2 - r;
-
- return 2;
-}
-/**
-* Find circle that touches inside of the curve, with radius matching the curvature, at time value \c t.
-* Because this method internally uses unitTangentAt, t should be smaller than 1.0 (see unitTangentAt).
-*/
-static Circle touching_circle( D2<SBasis> const &curve, double t, double tol=0.01 )
-{
- D2<SBasis> dM=derivative(curve);
- if ( are_near(L2sq(dM(t)),0.) ) {
- dM=derivative(dM);
- }
- if ( are_near(L2sq(dM(t)),0.) ) { // try second time
- dM=derivative(dM);
- }
- Piecewise<D2<SBasis> > unitv = unitVector(dM,tol);
- Piecewise<SBasis> dMlength = dot(Piecewise<D2<SBasis> >(dM),unitv);
- Piecewise<SBasis> k = cross(derivative(unitv),unitv);
- k = divide(k,dMlength,tol,3);
- double curv = k(t); // note that this value is signed
-
- Geom::Point normal = unitTangentAt(curve, t).cw();
- double radius = 1/curv;
- Geom::Point center = curve(t) + radius*normal;
- return Geom::Circle(center, fabs(radius));
-}
-
-std::vector<Geom::Path> split_at_cusps(const Geom::Path& in)
-{
- PathVector out = PathVector();
- Path temp = Path();
-
- for (unsigned i = 0; i < in.size(); i++) {
- temp.append(in[i]);
- if ( get_nodetype(in[i], in[i + 1]) != Geom::NODE_SMOOTH ) {
- out.push_back(temp);
- temp = Path();
- }
- }
- if (temp.size() > 0) {
- out.push_back(temp);
- }
- return out;
-}
-
-Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2<Geom::SBasis> const & sbasis_in)
-{
- std::vector<Geom::Point> temp;
- sbasis_to_bezier(temp, sbasis_in, 4);
- return Geom::CubicBezier( temp );
-}
-
-static boost::optional<Geom::Point> intersection_point(Geom::Point const & origin_a, Geom::Point const & vector_a, Geom::Point const & origin_b, Geom::Point const & vector_b)
-{
- Geom::Coord denom = cross(vector_b, vector_a);
- if (!Geom::are_near(denom,0.)) {
- Geom::Coord t = (cross(origin_a,vector_b) + cross(vector_b,origin_b)) / denom;
- return origin_a + t * vector_a;
- }
- return boost::none;
-}
-
-} // namespace Geom
-
-namespace Outline {
-
-typedef Geom::D2<Geom::SBasis> D2SB;
-typedef Geom::Piecewise<D2SB> PWD2;
-
-// UTILITY
-
-unsigned bezierOrder (const Geom::Curve* curve_in)
-{
- using namespace Geom;
- if ( const BezierCurve* bz = dynamic_cast<const BezierCurve*>(curve_in) ) {
- return bz->order();
- }
- return 0;
-}
-
-/**
- * @return true if the angle formed by the curves and their handles is greater than 180 degrees clockwise, otherwise false.
- */
-bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2)
-{
- Geom::Point start_point;
- Geom::Point cross_point = cbc1.finalPoint();
- Geom::Point end_point;
-
- if (cross_point != cbc2.initialPoint()) {
- printf("WARNING: Non-contiguous path in Outline::outside_angle()");
- return false;
- }
-
- Geom::CubicBezier cubicBezier = Geom::sbasis_to_cubicbezier(cbc1.toSBasis());
- start_point = cubicBezier [2];
-
- /*
- * Because the node editor does not yet support true quadratics, paths are converted to
- * cubic beziers in the node tool with degenerate handles on one side.
- */
-
- if (are_near(start_point, cross_point, 0.0000001)) {
- start_point = cubicBezier [1];
- }
- cubicBezier = Geom::sbasis_to_cubicbezier(cbc2.toSBasis());
- end_point = cubicBezier [1];
- if (are_near(end_point, cross_point, 0.0000001)) {
- end_point = cubicBezier [2];
- }
-
- // got our three points, now let's see what their clockwise angle is
-
- // Definition of a Graham scan
-
- /********************************************************************
- # Three points are a counter-clockwise turn if ccw > 0, clockwise if
- # ccw < 0, and collinear if ccw = 0 because ccw is a determinant that
- # gives the signed area of the triangle formed by p1, p2 and p3.
- function ccw(p1, p2, p3):
- return (p2.x - p1.x)*(p3.y - p1.y) - (p2.y - p1.y)*(p3.x - p1.x)
- *********************************************************************/
-
- double ccw = ( (cross_point.x() - start_point.x()) * (end_point.y() - start_point.y()) ) -
- ( (cross_point.y() - start_point.y()) * (end_point.x() - start_point.x()) );
- return ccw > 0;
-}
-
-// LINE JOINS
-
-typedef Geom::BezierCurveN<1u> BezierLine;
-
-/**
- * Removes the crossings on an interior join.
- * @param path_builder Contains the incoming segment; result is appended to this
- * @param outgoing The outgoing segment
- */
-void joinInside(Geom::Path& path_builder, Geom::Curve const& outgoing)
-{
- Geom::Curve const& incoming = path_builder.back();
-
- // Using Geom::crossings to find intersections between two curves
- Geom::Crossings cross = Geom::crossings(incoming, outgoing);
- if (!cross.empty()) {
- // Crossings found, create the join
- Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(incoming.toSBasis());
- cubic = cubic.subdivide(cross[0].ta).first;
- // erase the last segment, as we're going to overwrite it now
- path_builder.erase_last();
- path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS);
-
- cubic = Geom::sbasis_to_cubicbezier(outgoing.toSBasis());
- cubic = cubic.subdivide(cross[0].tb).second;
- path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS);
- } else {
- // No crossings occurred, or Geom::crossings() failed; default to bevel
- if (Geom::are_near(incoming.finalPoint(), outgoing.initialPoint())) {
- path_builder.appendNew<BezierLine>(outgoing.initialPoint());
- } else {
- path_builder.setFinal(outgoing.initialPoint());
- }
- }
-}
-
-/**
- * Try to create a miter join. Falls back to bevel if no miter can be created.
- * @param path_builder Path to append curves to; back() is the incoming curve
- * @param outgoing Outgoing curve.
- * @param miter_limit When mitering, don't exceed this length
- * @param line_width The thickness of the line.
- */
-void miter_curves(Geom::Path& path_builder, Geom::Curve const& outgoing, double miter_limit, double line_width)
-{
- using namespace Geom;
- Curve const& incoming = path_builder.back();
- Point tang1 = unitTangentAt(Geom::reverse(incoming.toSBasis()), 0.);
- Point tang2 = unitTangentAt(outgoing.toSBasis(), 0);
-
- boost::optional <Point> p = intersection_point (incoming.finalPoint(), tang1, outgoing.initialPoint(), tang2);
- if (p) {
- // check size of miter
- Point point_on_path = incoming.finalPoint() - rot90(tang1) * line_width;
- Coord len = distance(*p, point_on_path);
- if (len <= miter_limit) {
- // miter OK
- path_builder.appendNew<BezierLine>(*p);
- }
- }
- path_builder.appendNew<BezierLine>(outgoing.initialPoint());
-}
-
-/**
- * Smoothly extrapolate curves along a circular route. Falls back to miter if necessary.
- * @param path_builder Path to append curves to; back() is the incoming curve
- * @param outgoing Outgoing curve.
- * @param miter_limit When mitering, don't exceed this length
- * @param line_width The thickness of the line. Used for miter fallback.
- */
-void extrapolate_curves(Geom::Path& path_builder, Geom::Curve const& outgoing, double miter_limit, double line_width)
-{
- Geom::Curve const& incoming = path_builder.back();
- Geom::Point endPt = outgoing.initialPoint();
-
- // The method used when extrapolating curves fails to work when either side of the join to be extrapolated
- // is a line segment. When this situation is encountered, fall back to a regular miter join.
- bool lineProblem = (dynamic_cast<const BezierLine *>(&incoming)) || (dynamic_cast<const BezierLine *>(&outgoing));
- if (lineProblem == false) {
- // Geom::Point tang1 = Geom::unitTangentAt(Geom::reverse(incoming.toSBasis()), 0.);
- Geom::Point tang2 = Geom::unitTangentAt(outgoing.toSBasis(), 0);
-
- Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(incoming.toSBasis()), 0.);
- Geom::Circle circle2 = Geom::touching_circle(outgoing.toSBasis(), 0);
-
- Geom::Point points[2];
- int solutions = Geom::circle_circle_intersection(circle1, circle2, points[0], points[1]);
- if (solutions == 2) {
- Geom::Point sol(0,0);
- if ( dot(tang2,points[0]-endPt) > 0 ) {
- // points[0] is bad, choose points[1]
- sol = points[1];
- } else if ( dot(tang2,points[1]-endPt) > 0 ) { // points[0] could be good, now check points[1]
- // points[1] is bad, choose points[0]
- sol = points[0];
- } else {
- // both points are good, choose nearest
- sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ? points[0] : points[1];
- }
-
- Geom::EllipticalArc *arc0 = circle1.arc(incoming.finalPoint(), 0.5*(incoming.finalPoint()+sol), sol, true);
- Geom::EllipticalArc *arc1 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true);
- try {
- if (arc0) {
- path_builder.append (arc0->toSBasis());
- delete arc0;
- arc0 = NULL;
- } else {
- throw std::exception();
- }
-
- if (arc1) {
- path_builder.append (arc1->toSBasis());
- delete arc1;
- arc1 = NULL;
- } else {
- throw std::exception();
- }
-
- } catch (std::exception const & ex) {
- printf("WARNING: Error extrapolating line join: %s\n", ex.what());
- path_builder.appendNew<Geom::LineSegment>(endPt);
- }
- } else {
- // 1 or no solutions found, default to miter
- miter_curves(path_builder, outgoing, miter_limit, line_width);
- }
- } else {
- // Line segments exist
- miter_curves(path_builder, outgoing, miter_limit, line_width);
- }
-}
-
-/**
- * Extrapolate curves by reflecting them along the line that would be given by beveling the join.
- * @param path_builder Path to append curves to; back() is the incoming curve
- * @param outgoing Outgoing curve.
- * @param miter_limit When mitering, don't exceed this length
- * @param line_width The thickness of the line. Used for miter fallback.
- */
-void reflect_curves(Geom::Path& path_builder, Geom::Curve const& outgoing, double miter_limit, double line_width)
-{
- using namespace Geom;
- Curve const& incoming = path_builder.back();
- // On the outside, we'll take the incoming curve, the outgoing curve, and
- // reflect them over the line formed by taking the unit tangent vector at times
- // 0 and 1, respectively, rotated by 90 degrees.
- Crossings cross;
-
- // reflect curves along the line that would be given by beveling the join
- Point tang1 = unitTangentAt(reverse(incoming.toSBasis()), 0.);
- D2SB newcurve1 = incoming.toSBasis() * reflection(-rot90(tang1), incoming.finalPoint());
- CubicBezier bzr1 = sbasis_to_cubicbezier(reverse(newcurve1));
-
- Point tang2 = Geom::unitTangentAt(outgoing.toSBasis(), 0.);
- D2SB newcurve2 = outgoing.toSBasis() * reflection(-rot90(tang2), outgoing.initialPoint());
- CubicBezier bzr2 = sbasis_to_cubicbezier(reverse(newcurve2));
-
- cross = crossings(bzr1, bzr2);
- if (cross.empty()) {
- // paths don't cross, fall back to miter
- miter_curves(path_builder, outgoing, miter_limit, line_width);
- } else {
- // reflected join
- std::pair<CubicBezier, CubicBezier> sub1 = bzr1.subdivide(cross[0].ta);
- std::pair<CubicBezier, CubicBezier> sub2 = bzr2.subdivide(cross[0].tb);
-
- // TODO it seems as if a bug in 2geom sometimes doesn't catch the first
- // crossing of paths, but the second instead; but only sometimes.
- path_builder.appendNew <CubicBezier> (sub1.first[1], sub1.first[2], sub2.second[0]);
- path_builder.appendNew <CubicBezier> (sub2.second[1], sub2.second[2], outgoing.initialPoint());
- }
-}
-
-// Ideal function pointer we want to pass
-typedef void JoinFunc(Geom::Path& /*path_builder*/, Geom::Curve const& /*outgoing*/, double /*miter_limit*/, double /*line_width*/);
-
-/**
- * Helper function for repeated logic in outlineHalf.
- */
-static void outlineHelper(Geom::Path& path_builder, Geom::PathVector* path_vec, bool outside, double width, double miter, JoinFunc func)
-{
- Geom::Curve * cbc2 = path_vec->front()[0].duplicate();
-
- if (outside) {
- func(path_builder, *cbc2, miter, width);
- } else {
- joinInside(path_builder, *cbc2);
- }
-
- // store it
- Geom::Path temp_path = path_vec->front();
- if (!outside) {
- // erase the first segment since the inside join code already appended it
- temp_path.erase(temp_path.begin());
- }
-
- if (temp_path.initialPoint() != path_builder.finalPoint()) {
- temp_path.setInitial(path_builder.finalPoint());
- }
-
- path_builder.append(temp_path);
-
- delete cbc2;
-}
-
-/**
- * Offsets exactly one half of a bezier spline (path).
- * @param path_in The input path to use. (To create the other side use path_in.reverse() )
- * @param line_width the line width to use (usually you want to divide this by 2)
- * @param miter_limit the miter parameter
- * @param func Join function to apply at each join.
- */
-
-Geom::Path outlineHalf(const Geom::Path& path_in, double line_width, double miter_limit, JoinFunc func)
-{
- // NOTE: it is important to notice the distinction between a Geom::Path and a livarot ::Path here!
- // if you do not see "Geom::" there is a different function set!
-
- Geom::PathVector pv = split_at_cusps(path_in);
-
- ::Path to_outline;
- ::Path outlined_result;
-
- Geom::Path path_builder = Geom::Path(); // the path to store the result in
- Geom::PathVector* path_vec; // needed because livarot returns a pointer (TODO make this not a pointer)
-
- // Do two curves at a time for efficiency, since the join function needs to know the outgoing curve as well
- const size_t k = pv.size();
- for (size_t u = 0; u < k; u += 2) {
- to_outline = Path();
- outlined_result = Path();
-
- to_outline.LoadPath(pv[u], Geom::identity(), false, false);
- to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10);
- // now a curve has been outside outlined and loaded into outlined_result
-
- // get the Geom::Path
- path_vec = outlined_result.MakePathVector();
-
- // on the first run through, there is no join
- if (u == 0) {
- path_builder.start(path_vec->front().initialPoint());
- path_builder.append(path_vec->front());
- } else {
- outlineHelper(path_builder, path_vec, outside_angle(pv[u-1][pv[u-1].size()-1], pv[u][0]), line_width, miter_limit, func);
- }
-
- // outline the next segment, but don't store it yet
- if (path_vec)
- delete path_vec;
- path_vec = NULL;
-
- // odd number of paths
- if (u < k - 1) {
- outlined_result = Path();
- to_outline = Path();
-
- to_outline.LoadPath(pv[u+1], Geom::Affine(), false, false);
- to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10);
-
- path_vec = outlined_result.MakePathVector();
- outlineHelper(path_builder, path_vec, outside_angle(pv[u][pv[u].size()-1], pv[u+1][0]), line_width, miter_limit, func);
-
- if (path_vec)
- delete path_vec;
- path_vec = NULL;
- }
- }
-
- if (path_in.closed()) {
- Geom::Curve * cbc1;
- Geom::Curve * cbc2;
-
- if ( path_in[path_in.size()].isDegenerate() ) {
- // handle case for last segment curved
- outlined_result = Path();
- to_outline = Path();
-
- Geom::Path oneCurve; oneCurve.append(path_in[0]);
-
- to_outline.LoadPath(oneCurve, Geom::Affine(), false, false);
- to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10);
-
- path_vec = outlined_result.MakePathVector();
-
- cbc1 = path_builder[path_builder.size() - 1].duplicate();
- cbc2 = path_vec->front()[0].duplicate();
-
- delete path_vec;
- } else {
- // handle case for last segment straight
- // since the path doesn't actually give us access to it, we'll do it ourselves
- outlined_result = Path();
- to_outline = Path();
-
- Geom::Path oneCurve; oneCurve.append(Geom::LineSegment(path_in.finalPoint(), path_in.initialPoint()));
-
- to_outline.LoadPath(oneCurve, Geom::Affine(), false, false);
- to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10);
-
- path_vec = outlined_result.MakePathVector();
-
- cbc1 = path_builder[path_builder.size() - 1].duplicate();
- cbc2 = (*path_vec)[0] [0].duplicate();
-
- outlineHelper(path_builder, path_vec, outside_angle(path_in[path_in.size()-1], oneCurve[0]), line_width, miter_limit, func);
-
- delete cbc1;
- cbc1 = cbc2->duplicate();
- delete path_vec;
-
- oneCurve = Geom::Path(); oneCurve.append(path_in[0]);
-
- to_outline.LoadPath(oneCurve, Geom::Affine(), false, false);
- to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10);
-
- path_vec = outlined_result.MakePathVector();
- delete cbc2; cbc2 = (*path_vec)[0] [0].duplicate();
- delete path_vec;
- }
-
- Geom::Path temporary;
- temporary.append(*cbc1);
-
- Geom::Curve const & prev_curve = path_in[path_in.size()].isDegenerate() ? path_in[path_in.size() - 1] : path_in[path_in.size()];
- Geom::Path isStraight;
- isStraight.append(prev_curve);
- isStraight.append(path_in[0]);
- // does closing path require a join?
- if (Geom::split_at_cusps(isStraight).size() > 1) {
- bool outside = outside_angle(prev_curve, path_in[0]);
- if (outside) {
- func(temporary, *cbc2, miter_limit, line_width);
- } else {
- joinInside(temporary, *cbc2);
- path_builder.erase(path_builder.begin());
- }
-
- // extract the appended curves
- path_builder.erase_last();
- if (Geom::are_near(path_builder.finalPoint(), temporary.initialPoint())) {
- path_builder.setFinal(temporary.initialPoint());
- } else {
- path_builder.appendNew<BezierLine>(temporary.initialPoint());
- }
- path_builder.append(temporary);
- } else {
- // closing path does not require a join
- path_builder.setFinal(path_builder.initialPoint());
- }
- path_builder.close();
-
- if (cbc1) delete cbc1;
- if (cbc2) delete cbc2;
- }
-
- return path_builder;
-}
-
-Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtTypeMod butt, double miter_lim, bool extrapolate, double start_lean, double end_lean)
-{
- Geom::PathVector path_out;
-
- unsigned pv_size = path_in.size();
- for (unsigned i = 0; i < pv_size; i++) {
-
- if (path_in[i].size() > 1) {
- Geom::Path with_direction;
- Geom::Path against_direction;
-
- with_direction = Outline::outlineHalf(path_in[i], -line_width, miter_lim, extrapolate ? extrapolate_curves : reflect_curves);
- against_direction = Outline::outlineHalf(path_in[i].reverse(), -line_width, miter_lim, extrapolate ? extrapolate_curves : reflect_curves);
-
- Geom::PathBuilder pb;
-
- pb.moveTo(with_direction.initialPoint());
- pb.append(with_direction);
-
- //add in our line caps
- if (!path_in[i].closed()) {
- switch (butt) {
- case BUTT_STRAIGHT:
- pb.lineTo(against_direction.initialPoint());
- break;
- case BUTT_ROUND:
- pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, against_direction.initialPoint() );
- break;
- case BUTT_POINTY: {
- Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.);
- double radius = 0.5 * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint());
- Geom::Point midpoint = 0.5 * (with_direction.finalPoint() + against_direction.initialPoint()) + radius*end_deriv;
- pb.lineTo(midpoint);
- pb.lineTo(against_direction.initialPoint());
- break;
- }
- case BUTT_SQUARE: {
- Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.);
- double radius = 0.5 * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint());
- pb.lineTo(with_direction.finalPoint() + radius*end_deriv);
- pb.lineTo(against_direction.initialPoint() + radius*end_deriv);
- pb.lineTo(against_direction.initialPoint());
- break;
- }
- case BUTT_LEANED: {
- Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.);
- double maxRadius = (end_lean+0.5) * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint());
- double minRadius = ((end_lean*-1)+0.5) * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint());
- pb.lineTo(with_direction.finalPoint() + maxRadius*end_deriv);
- pb.lineTo(against_direction.initialPoint() + minRadius*end_deriv);
- pb.lineTo(against_direction.initialPoint());
- break;
- }
- }
- } else {
- pb.moveTo(against_direction.initialPoint());
- }
-
- pb.append(against_direction);
-
- //cap (if necessary)
- if (!path_in[i].closed()) {
- switch (butt) {
- case BUTT_STRAIGHT:
- pb.lineTo(with_direction.initialPoint());
- break;
- case BUTT_ROUND:
- pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, with_direction.initialPoint() );
- break;
- case BUTT_POINTY: {
- Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.);
- double radius = 0.5 * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint());
- Geom::Point midpoint = 0.5 * (against_direction.finalPoint() + with_direction.initialPoint()) + radius*end_deriv;
- pb.lineTo(midpoint);
- pb.lineTo(with_direction.initialPoint());
- break;
- }
- case BUTT_SQUARE: {
- Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.);
- double radius = 0.5 * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint());
- pb.lineTo(against_direction.finalPoint() + radius*end_deriv);
- pb.lineTo(with_direction.initialPoint() + radius*end_deriv);
- pb.lineTo(with_direction.initialPoint());
- break;
- }
- case BUTT_LEANED: {
- Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.);
- double maxRadius = (start_lean+0.5) * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint());
- double minRadius = ((start_lean*-1)+0.5) * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint());
- pb.lineTo(against_direction.finalPoint() + minRadius*end_deriv);
- pb.lineTo(with_direction.initialPoint() + maxRadius*end_deriv);
- pb.lineTo(with_direction.initialPoint());
- break;
- }
- }
- }
- pb.flush();
- path_out.push_back(pb.peek()[0]);
- if (path_in[i].closed()) {
- path_out.push_back(pb.peek()[1]);
- }
- } else {
- Path p = Path();
- Path outlinepath = Path();
- ButtType original_butt;
- switch (butt) {
- case BUTT_STRAIGHT:
- original_butt = butt_straight;
- break;
- case BUTT_ROUND:
- original_butt = butt_round;
- break;
- case butt_pointy: {
- original_butt = butt_pointy;
- break;
- }
- case BUTT_SQUARE: {
- original_butt = butt_square;
- break;
- }
- case BUTT_LEANED: {
- original_butt = butt_straight;
- break;
- }
- }
- p.LoadPath(path_in[i], Geom::Affine(), false, false);
- p.Outline(&outlinepath, line_width / 2, static_cast<join_typ>(join), original_butt, miter_lim);
- Geom::PathVector *pv_p = outlinepath.MakePathVector();
- //somewhat hack-ish
- path_out.push_back( (*pv_p)[0].reverse() );
- if (pv_p) delete pv_p;
- }
- }
- return path_out;
-}
-
-#define miter_lim fabs(line_width * miter_limit)
-
-Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line_width, ButtTypeMod linecap_type, LineJoinType linejoin_type, double miter_limit, double start_lean, double end_lean)
-{
- std::vector<Geom::Path> path_out = std::vector<Geom::Path>();
- if (path_in.empty()) {
- return path_out;
- }
- Path p = Path();
- Path outlinepath = Path();
- for (unsigned i = 0; i < path_in.size(); i++) {
- p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true));
- }
-
- // magic!
- ButtType original_butt;
- switch (linecap_type) {
- case BUTT_STRAIGHT:
- original_butt = butt_straight;
- break;
- case BUTT_ROUND:
- original_butt = butt_round;
- break;
- case butt_pointy: {
- original_butt = butt_pointy;
- break;
- }
- case BUTT_SQUARE: {
- original_butt = butt_square;
- break;
- }
- case BUTT_LEANED: {
- original_butt = butt_straight;
- break;
- }
- }
- if (linejoin_type <= LINEJOIN_POINTY) {
- p.Outline(&outlinepath, line_width / 2, static_cast<join_typ>(linejoin_type),
- original_butt, miter_lim);
- // fix memory leak
- std::vector<Geom::Path> *pv_p = outlinepath.MakePathVector();
- path_out = *pv_p;
- delete pv_p;
-
- } else if (linejoin_type == LINEJOIN_REFLECTED) {
- // reflected arc join
- path_out = outlinePath(path_in, line_width, static_cast<LineJoinType>(linejoin_type),
- linecap_type , miter_lim, false, start_lean, end_lean);
-
- } else if (linejoin_type == LINEJOIN_EXTRAPOLATED) {
- // extrapolated arc join
- path_out = outlinePath(path_in, line_width, LINEJOIN_STRAIGHT, linecap_type, miter_lim, true, start_lean, end_lean);
- }
-
- return path_out;
-}
-
-Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit)
-{
-
- Geom::Path path_out;
-
- if (linejoin_type <= LINEJOIN_POINTY || path_in.size() <= 1) {
-
- Geom::PathVector * pathvec;
-
- Path path_tangent = Path();
- Path path_outline = Path();
- path_outline.LoadPath(path_in, Geom::Affine(), false, false);
- path_outline.OutsideOutline(&path_tangent, line_width / 2, static_cast<join_typ>(linejoin_type), butt_straight, miter_lim);
-
- pathvec = path_tangent.MakePathVector();
- path_out = pathvec->front();
- delete pathvec;
- return path_out;
- } else if (linejoin_type == LINEJOIN_REFLECTED) {
- path_out = outlineHalf(path_in, line_width, miter_lim, reflect_curves);
- return path_out;
- } else if (linejoin_type == LINEJOIN_EXTRAPOLATED) {
- path_out = outlineHalf(path_in, line_width, miter_lim, extrapolate_curves);
- return path_out;
- }
- return path_out;
-}
-
-} // namespace Outline
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8 :
diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h
deleted file mode 100644
index c17584be2..000000000
--- a/src/live_effects/pathoutlineprovider.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef SEEN_PATH_OUTLINE_H
-#define SEEN_PATH_OUTLINE_H
-
-/* Author:
- * Liam P. White <inkscapebrony@gmail.com>
- *
- * Copyright (C) 2014 Author
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <livarot/Path.h>
-#include <livarot/LivarotDefs.h>
-
-enum LineJoinType {
- LINEJOIN_STRAIGHT,
- LINEJOIN_ROUND,
- LINEJOIN_POINTY,
- LINEJOIN_REFLECTED,
- LINEJOIN_EXTRAPOLATED
-};
-enum ButtTypeMod {
- BUTT_STRAIGHT,
- BUTT_ROUND,
- BUTT_SQUARE,
- BUTT_POINTY,
- BUTT_LEANED
-};
-
-namespace Geom
-{
- Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2<Geom::SBasis> const & sbasis_in);
- std::vector<Geom::Path> split_at_cusps(const Geom::Path& in);
-}
-
-namespace Outline
-{
- unsigned bezierOrder (const Geom::Curve* curve_in);
- std::vector<Geom::Path> PathVectorOutline(std::vector<Geom::Path> const & path_in, double line_width, ButtTypeMod linecap_type,
- LineJoinType linejoin_type, double miter_limit, double start_lean = 0, double end_lean = 0);
- Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit);
-}
-
-#endif // SEEN_PATH_OUTLINE_H
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/svg-profile.h b/src/svg-profile.h
index 9d221fc76..8945ee313 100644
--- a/src/svg-profile.h
+++ b/src/svg-profile.h
@@ -74,7 +74,7 @@ public:
SVG_PRINT_1_1, /**< */
- PROFILE_UNIQUE_CNT, /**< A marker to seperate between the entires
+ PROFILE_UNIQUE_CNT, /**< A marker to separate between the entires
that are unique, and those which are
aggregates of them. */
diff --git a/src/trace/potrace/auxiliary.h b/src/trace/potrace/auxiliary.h
index b7480bbb8..dbf124d7c 100644
--- a/src/trace/potrace/auxiliary.h
+++ b/src/trace/potrace/auxiliary.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -8,6 +8,8 @@
#ifndef AUXILIARY_H
#define AUXILIARY_H
+#include <stdlib.h>
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -75,31 +77,4 @@ static inline int floordiv(int a, int n) {
#define sq(a) ((a)*(a))
#define cu(a) ((a)*(a)*(a))
-/* ---------------------------------------------------------------------- */
-/* deterministically and efficiently hash (x,y) into a pseudo-random bit */
-static inline int detrand(int x, int y) {
- unsigned int z;
- static const unsigned char t[256] = {
- /* non-linear sequence: constant term of inverse in GF(8),
- mod x^8+x^4+x^3+x+1 */
- 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1,
- 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,
- 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0,
- 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
- 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0,
- 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
- 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- };
-
- /* 0x04b3e375 and 0x05a8ef93 are chosen to contain every possible
- 5-bit sequence */
- z = ((0x04b3e375 * x) ^ y) * 0x05a8ef93;
- z = t[z & 0xff] ^ t[(z>>8) & 0xff] ^ t[(z>>16) & 0xff] ^ t[(z>>24) & 0xff];
- return z;
-}
-
#endif /* AUXILIARY_H */
diff --git a/src/trace/potrace/bitmap.h b/src/trace/potrace/bitmap.h
index 2df04b46f..086bbb046 100644
--- a/src/trace/potrace/bitmap.h
+++ b/src/trace/potrace/bitmap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -7,6 +7,7 @@
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
/* The bitmap type is defined in potracelib.h */
#include "potracelib.h"
@@ -27,7 +28,7 @@
/* macros for accessing pixel at index (x,y). U* macros omit the
bounds check. */
-#define bm_scanline(bm, y) ((bm)->map + (y)*(bm)->dy)
+#define bm_scanline(bm, y) ((bm)->map + (ssize_t)(y)*(ssize_t)(bm)->dy)
#define bm_index(bm, x, y) (&bm_scanline(bm, y)[(x)/BM_WORDBITS])
#define bm_mask(x) (BM_HIBIT >> ((x) & (BM_WORDBITS-1)))
#define bm_range(x, a) ((int)(x) >= 0 && (int)(x) < (a))
@@ -51,10 +52,18 @@ static inline void bm_free(potrace_bitmap_t *bm) {
free(bm);
}
-/* return new un-initialized bitmap. NULL with errno on error */
+/* return new un-initialized bitmap. NULL with errno on error.
+ Assumes w, h >= 0. */
static inline potrace_bitmap_t *bm_new(int w, int h) {
potrace_bitmap_t *bm;
- int dy = (w + BM_WORDBITS - 1) / BM_WORDBITS;
+ int dy = w == 0 ? 0 : (w - 1) / BM_WORDBITS + 1;
+ ssize_t size = (ssize_t)dy * (ssize_t)h * (ssize_t)BM_WORDSIZE;
+
+ /* check for overflow error */
+ if (size < 0 || size / h / dy != BM_WORDSIZE) {
+ errno = ENOMEM;
+ return NULL;
+ }
bm = (potrace_bitmap_t *) malloc(sizeof(potrace_bitmap_t));
if (!bm) {
@@ -63,7 +72,7 @@ static inline potrace_bitmap_t *bm_new(int w, int h) {
bm->w = w;
bm->h = h;
bm->dy = dy;
- bm->map = (potrace_word *) malloc(dy * h * BM_WORDSIZE);
+ bm->map = (potrace_word *) malloc(size);
if (!bm->map) {
free(bm);
return NULL;
@@ -73,23 +82,29 @@ static inline potrace_bitmap_t *bm_new(int w, int h) {
/* clear the given bitmap. Set all bits to c. */
static inline void bm_clear(potrace_bitmap_t *bm, int c) {
- memset(bm->map, c ? -1 : 0, bm->dy * bm->h * BM_WORDSIZE);
+ /* Note: if the bitmap was created with bm_new, then it is
+ guaranteed that size will fit into the ssize_t type. */
+ ssize_t size = (ssize_t)bm->dy * (ssize_t)bm->h * (ssize_t)BM_WORDSIZE;
+ memset(bm->map, c ? -1 : 0, size);
}
/* duplicate the given bitmap. Return NULL on error with errno set. */
static inline potrace_bitmap_t *bm_dup(const potrace_bitmap_t *bm) {
potrace_bitmap_t *bm1 = bm_new(bm->w, bm->h);
+ ssize_t size = (ssize_t)bm->dy * (ssize_t)bm->h * (ssize_t)BM_WORDSIZE;
if (!bm1) {
return NULL;
}
- memcpy(bm1->map, bm->map, bm->dy * bm->h * BM_WORDSIZE);
+ memcpy(bm1->map, bm->map, size);
return bm1;
}
/* invert the given bitmap. */
static inline void bm_invert(potrace_bitmap_t *bm) {
- int i;
- for (i = 0; i < bm->dy * bm->h; i++) {
+ ssize_t i;
+ ssize_t size = (ssize_t)bm->dy * (ssize_t)bm->h;
+
+ for (i = 0; i < size; i++) {
bm->map[i] ^= BM_ALLBITS;
}
}
diff --git a/src/trace/potrace/bitops.h b/src/trace/potrace/bitops.h
new file mode 100644
index 000000000..cff734a46
--- /dev/null
+++ b/src/trace/potrace/bitops.h
@@ -0,0 +1,83 @@
+/* Copyright (C) 2001-2015 Peter Selinger.
+ This file is part of Potrace. It is free software and it is covered
+ by the GNU General Public License. See the file COPYING for details. */
+
+
+/* bits.h: this file defines some macros for bit manipulations. We
+ provide a generic implementation, as well as machine- and
+ compiler-specific fast implementations */
+
+/* lobit: return the position of the rightmost "1" bit of an int, or
+ 32 if none. hibit: return 1 + the position of the leftmost "1" bit
+ of an int, or 0 if none. Note: these functions work on 32-bit
+ integers. */
+
+#ifndef BITOPS_H
+#define BITOPS_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* ---------------------------------------------------------------------- */
+/* machine specific macros */
+
+#if defined(HAVE_I386)
+
+static inline unsigned int lobit(unsigned int x) {
+ unsigned int res;
+ asm ("bsf %1,%0\n\t"
+ "jnz 0f\n\t"
+ "movl $32,%0\n"
+ "0:"
+ : "=r" (res)
+ : "r" (x)
+ : "cc");
+ return res;
+}
+
+static inline unsigned int hibit(unsigned int x) {
+ unsigned int res;
+
+ asm ("bsr %1,%0\n\t"
+ "jnz 0f\n\t"
+ "movl $-1,%0\n"
+ "0:"
+ : "=r" (res)
+ : "r" (x)
+ : "cc");
+ return res+1;
+}
+
+/* ---------------------------------------------------------------------- */
+#else /* generic macros */
+
+static inline unsigned int lobit(unsigned int x) {
+ unsigned int res = 32;
+ while (x & 0xffffff) {
+ x <<= 8;
+ res -= 8;
+ }
+ while (x) {
+ x <<= 1;
+ res -= 1;
+ }
+ return res;
+}
+
+static inline unsigned int hibit(unsigned int x) {
+ unsigned int res = 0;
+ while (x > 0xff) {
+ x >>= 8;
+ res += 8;
+ }
+ while (x) {
+ x >>= 1;
+ res += 1;
+ }
+ return res;
+}
+
+#endif
+
+#endif /* BITOPS_H */
diff --git a/src/trace/potrace/curve.cpp b/src/trace/potrace/curve.cpp
index d2e32aa7b..e6a9a4721 100644
--- a/src/trace/potrace/curve.cpp
+++ b/src/trace/potrace/curve.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -12,8 +12,8 @@
#include "lists.h"
#include "curve.h"
-#define SAFE_MALLOC(var, n, typ) \
- if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error
+#define SAFE_CALLOC(var, n, typ) \
+ if ((var = (typ *)calloc(n, sizeof(typ))) == NULL) goto calloc_error
/* ---------------------------------------------------------------------- */
/* allocate and free path objects */
@@ -22,14 +22,14 @@ path_t *path_new(void) {
path_t *p = NULL;
privpath_t *priv = NULL;
- SAFE_MALLOC(p, 1, path_t);
+ SAFE_CALLOC(p, 1, path_t);
memset(p, 0, sizeof(path_t));
- SAFE_MALLOC(priv, 1, privpath_t);
+ SAFE_CALLOC(priv, 1, privpath_t);
memset(priv, 0, sizeof(privpath_t));
p->priv = priv;
return p;
- malloc_error:
+ calloc_error:
free(p);
free(priv);
return NULL;
@@ -81,15 +81,15 @@ typedef dpoint_t dpoint3_t[3];
int privcurve_init(privcurve_t *curve, int n) {
memset(curve, 0, sizeof(privcurve_t));
curve->n = n;
- SAFE_MALLOC(curve->tag, n, int);
- SAFE_MALLOC(curve->c, n, dpoint3_t);
- SAFE_MALLOC(curve->vertex, n, dpoint_t);
- SAFE_MALLOC(curve->alpha, n, double);
- SAFE_MALLOC(curve->alpha0, n, double);
- SAFE_MALLOC(curve->beta, n, double);
+ SAFE_CALLOC(curve->tag, n, int);
+ SAFE_CALLOC(curve->c, n, dpoint3_t);
+ SAFE_CALLOC(curve->vertex, n, dpoint_t);
+ SAFE_CALLOC(curve->alpha, n, double);
+ SAFE_CALLOC(curve->alpha0, n, double);
+ SAFE_CALLOC(curve->beta, n, double);
return 0;
- malloc_error:
+ calloc_error:
free(curve->tag);
free(curve->c);
free(curve->vertex);
diff --git a/src/trace/potrace/curve.h b/src/trace/potrace/curve.h
index 6ceae0c3a..feb95b39b 100644
--- a/src/trace/potrace/curve.h
+++ b/src/trace/potrace/curve.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
diff --git a/src/trace/potrace/decompose.cpp b/src/trace/potrace/decompose.cpp
index 6c27a7ebf..7628b202d 100644
--- a/src/trace/potrace/decompose.cpp
+++ b/src/trace/potrace/decompose.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -15,6 +15,33 @@
#include "decompose.h"
#include "progress.h"
+/* ---------------------------------------------------------------------- */
+/* deterministically and efficiently hash (x,y) into a pseudo-random bit */
+
+static inline int detrand(int x, int y) {
+ unsigned int z;
+ static const unsigned char t[256] = {
+ /* non-linear sequence: constant term of inverse in GF(8),
+ mod x^8+x^4+x^3+x+1 */
+ 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0,
+ 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,
+ 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0,
+ 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
+ 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0,
+ 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
+ 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ };
+
+ /* 0x04b3e375 and 0x05a8ef93 are chosen to contain every possible
+ 5-bit sequence */
+ z = ((0x04b3e375 * x) ^ y) * 0x05a8ef93;
+ z = t[z & 0xff] ^ t[(z>>8) & 0xff] ^ t[(z>>16) & 0xff] ^ t[(z>>24) & 0xff];
+ return z;
+}
/* ---------------------------------------------------------------------- */
/* auxiliary bitmap manipulations */
diff --git a/src/trace/potrace/decompose.h b/src/trace/potrace/decompose.h
index 89b01e504..8ae89b8ad 100644
--- a/src/trace/potrace/decompose.h
+++ b/src/trace/potrace/decompose.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
diff --git a/src/trace/potrace/greymap.cpp b/src/trace/potrace/greymap.cpp
index e116021c1..4ef2ec8df 100644
--- a/src/trace/potrace/greymap.cpp
+++ b/src/trace/potrace/greymap.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -9,8 +9,10 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <errno.h>
#include "greymap.h"
+#include "bitops.h"
#define INTBITS (8*sizeof(int))
@@ -22,10 +24,17 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp);
/* ---------------------------------------------------------------------- */
/* basic greymap routines */
-/* return new un-initialized greymap. NULL with errno on error */
-
+/* return new un-initialized greymap. NULL with errno on error.
+ Assumes w, h >= 0. */
greymap_t *gm_new(int w, int h) {
greymap_t *gm;
+ ssize_t size = (ssize_t)w * (ssize_t)h * (ssize_t)sizeof(signed short int);
+
+ /* check for overflow error */
+ if (size < 0 || size / w / h != sizeof(signed short int)) {
+ errno = ENOMEM;
+ return NULL;
+ }
gm = (greymap_t *) malloc(sizeof(greymap_t));
if (!gm) {
@@ -33,7 +42,7 @@ greymap_t *gm_new(int w, int h) {
}
gm->w = w;
gm->h = h;
- gm->map = (signed short int *) malloc(w*h*sizeof(signed short int));
+ gm->map = (signed short int *) malloc(size);
if (!gm->map) {
free(gm);
return NULL;
@@ -405,6 +414,10 @@ struct bmp_info_s {
unsigned int YpixelsPerM;
unsigned int ncolors; /* number of colors in palette */
unsigned int ColorsImportant;
+ unsigned int RedMask;
+ unsigned int GreenMask;
+ unsigned int BlueMask;
+ unsigned int AlphaMask;
unsigned int ctbits; /* sample size for color table */
int topdown; /* top-down mode? */
};
@@ -495,6 +508,7 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
int col[2];
unsigned int bitbuf;
unsigned int n;
+ unsigned int redshift, greenshift, blueshift;
gm_read_error = NULL;
gm = NULL;
@@ -523,12 +537,24 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
TRY(bmp_readint(f, 4, &bmpinfo.YpixelsPerM));
TRY(bmp_readint(f, 4, &bmpinfo.ncolors));
TRY(bmp_readint(f, 4, &bmpinfo.ColorsImportant));
- if ((signed int)bmpinfo.h < 0) {
- bmpinfo.h = -bmpinfo.h;
+ if (bmpinfo.InfoSize >= 108) { /* V4 and V5 bitmaps */
+ TRY(bmp_readint(f, 4, &bmpinfo.RedMask));
+ TRY(bmp_readint(f, 4, &bmpinfo.GreenMask));
+ TRY(bmp_readint(f, 4, &bmpinfo.BlueMask));
+ TRY(bmp_readint(f, 4, &bmpinfo.AlphaMask));
+ }
+ if (bmpinfo.w > 0x7fffffff) {
+ goto format_error;
+ }
+ if (bmpinfo.h > 0x7fffffff) {
+ bmpinfo.h = (-bmpinfo.h) & 0xffffffff;
bmpinfo.topdown = 1;
} else {
bmpinfo.topdown = 0;
}
+ if (bmpinfo.h > 0x7fffffff) {
+ goto format_error;
+ }
} else if (bmpinfo.InfoSize == 12) {
/* old OS/2 format */
bmpinfo.ctbits = 24; /* sample size in color table */
@@ -543,6 +569,11 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
goto format_error;
}
+ if (bmpinfo.comp == 3 && bmpinfo.InfoSize < 108) {
+ /* bitfield feature is only understood with V4 and V5 format */
+ goto format_error;
+ }
+
/* forward to color table (e.g., if bmpinfo.InfoSize == 64) */
TRY(bmp_forward(f, 14+bmpinfo.InfoSize));
@@ -557,7 +588,7 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
/* color table, present only if bmpinfo.bits <= 8. */
if (bmpinfo.bits <= 8) {
- coltable = (int *) malloc(bmpinfo.ncolors * sizeof(int));
+ coltable = (int *) calloc(bmpinfo.ncolors, sizeof(int));
if (!coltable) {
goto std_error;
}
@@ -651,6 +682,22 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
}
break;
+ case 0x320: /* 32-bit encoding with bitfields */
+ redshift = lobit(bmpinfo.RedMask);
+ greenshift = lobit(bmpinfo.GreenMask);
+ blueshift = lobit(bmpinfo.BlueMask);
+
+ for (y=0; y<bmpinfo.h; y++) {
+ bmp_pad_reset();
+ for (x=0; x<bmpinfo.w; x++) {
+ TRY_EOF(bmp_readint(f, bmpinfo.bits/8, &c));
+ c = ((c & bmpinfo.RedMask) >> redshift) + ((c & bmpinfo.GreenMask) >> greenshift) + ((c & bmpinfo.BlueMask) >> blueshift);
+ GM_UPUT(gm, x, ycorr(y), c/3);
+ }
+ TRY(bmp_pad(f));
+ }
+ break;
+
case 0x204: /* 4-bit runlength compressed encoding (RLE4) */
x = 0;
y = 0;
diff --git a/src/trace/potrace/greymap.h b/src/trace/potrace/greymap.h
index 1fb5426c1..8c9db9bbf 100644
--- a/src/trace/potrace/greymap.h
+++ b/src/trace/potrace/greymap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -7,6 +7,7 @@
#define GREYMAP_H
#include <stdio.h>
+#include <stdlib.h>
/* internal format for greymaps. Note: in this format, rows are
ordered from bottom to top. The pixels in each row are given from
@@ -22,7 +23,7 @@ typedef struct greymap_s greymap_t;
/* macros for accessing pixel at index (x,y). Note that the origin is
in the *lower* left corner. U* macros omit the bounds check. */
-#define gm_index(gm, x, y) (&(gm)->map[(x)+(y)*(gm)->w])
+#define gm_index(gm, x, y) (&(gm)->map[(x)+(y)*(ssize_t)(gm)->w])
#define gm_safe(gm, x, y) ((int)(x)>=0 && (int)(x)<(gm)->w && (int)(y)>=0 && (int)(y)<(gm)->h)
#define gm_bound(x, m) ((x)<0 ? 0 : (x)>=(m) ? (m)-1 : (x))
#define GM_UGET(gm, x, y) (*gm_index(gm, x, y))
diff --git a/src/trace/potrace/lists.h b/src/trace/potrace/lists.h
index 078129afc..394262c23 100644
--- a/src/trace/potrace/lists.h
+++ b/src/trace/potrace/lists.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
diff --git a/src/trace/potrace/potracelib.cpp b/src/trace/potrace/potracelib.cpp
index 0fb835593..b5463d676 100644
--- a/src/trace/potrace/potracelib.cpp
+++ b/src/trace/potrace/potracelib.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
diff --git a/src/trace/potrace/potracelib.h b/src/trace/potrace/potracelib.h
index cd142a6e1..0a6ddbf1f 100644
--- a/src/trace/potrace/potracelib.h
+++ b/src/trace/potrace/potracelib.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
diff --git a/src/trace/potrace/progress.h b/src/trace/potrace/progress.h
index 3e1dfb34e..ecc2ba217 100644
--- a/src/trace/potrace/progress.h
+++ b/src/trace/potrace/progress.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
diff --git a/src/trace/potrace/render.cpp b/src/trace/potrace/render.cpp
index 3c8f79c05..4f44ae6a6 100644
--- a/src/trace/potrace/render.cpp
+++ b/src/trace/potrace/render.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -52,7 +52,7 @@ render_t *render_new(greymap_t *gm) {
}
memset(rm, 0, sizeof(render_t));
rm->gm = gm;
- rm->incrow_buf = (int *) malloc(gm->h * sizeof(int));
+ rm->incrow_buf = (int *) calloc(gm->h, sizeof(int));
if (!rm->incrow_buf) {
free(rm);
return NULL;
diff --git a/src/trace/potrace/render.h b/src/trace/potrace/render.h
index ad600156a..0caaedff6 100644
--- a/src/trace/potrace/render.h
+++ b/src/trace/potrace/render.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
diff --git a/src/trace/potrace/trace.cpp b/src/trace/potrace/trace.cpp
index f1e88a908..469262b67 100644
--- a/src/trace/potrace/trace.cpp
+++ b/src/trace/potrace/trace.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -21,8 +21,8 @@
#define COS179 -0.999847695156 /* the cosine of 179 degrees */
/* ---------------------------------------------------------------------- */
-#define SAFE_MALLOC(var, n, typ) \
- if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error
+#define SAFE_CALLOC(var, n, typ) \
+ if ((var = (typ *)calloc(n, sizeof(typ))) == NULL) goto calloc_error
/* ---------------------------------------------------------------------- */
/* auxiliary functions */
@@ -265,7 +265,7 @@ static int calc_sums(privpath_t *pp) {
int i, x, y;
int n = pp->len;
- SAFE_MALLOC(pp->sums, pp->len+1, sums_t);
+ SAFE_CALLOC(pp->sums, pp->len+1, sums_t);
/* origin */
pp->x0 = pp->pt[0].x;
@@ -284,7 +284,7 @@ static int calc_sums(privpath_t *pp) {
}
return 0;
- malloc_error:
+ calloc_error:
return 1;
}
@@ -331,8 +331,8 @@ static int calc_lon(privpath_t *pp) {
point_t dk; /* direction of k-k1 */
int a, b, c, d;
- SAFE_MALLOC(pivk, n, int);
- SAFE_MALLOC(nc, n, int);
+ SAFE_CALLOC(pivk, n, int);
+ SAFE_CALLOC(nc, n, int);
/* initialize the nc data structure. Point from each point to the
furthest future point to which it is connected by a vertical or
@@ -349,7 +349,7 @@ static int calc_lon(privpath_t *pp) {
nc[i] = k;
}
- SAFE_MALLOC(pp->lon, n, int);
+ SAFE_CALLOC(pp->lon, n, int);
/* determine pivot points: for each i, let pivk[i] be the furthest k
such that all j with i<j<k lie on a line connecting i,k. */
@@ -458,7 +458,7 @@ static int calc_lon(privpath_t *pp) {
free(nc);
return 0;
- malloc_error:
+ calloc_error:
free(pivk);
free(nc);
return 1;
@@ -537,12 +537,12 @@ static int bestpolygon(privpath_t *pp)
double best;
int c;
- SAFE_MALLOC(pen, n+1, double);
- SAFE_MALLOC(prev, n+1, int);
- SAFE_MALLOC(clip0, n, int);
- SAFE_MALLOC(clip1, n+1, int);
- SAFE_MALLOC(seg0, n+1, int);
- SAFE_MALLOC(seg1, n+1, int);
+ SAFE_CALLOC(pen, n+1, double);
+ SAFE_CALLOC(prev, n+1, int);
+ SAFE_CALLOC(clip0, n, int);
+ SAFE_CALLOC(clip1, n+1, int);
+ SAFE_CALLOC(seg0, n+1, int);
+ SAFE_CALLOC(seg1, n+1, int);
/* calculate clipped paths */
for (i=0; i<n; i++) {
@@ -604,7 +604,7 @@ static int bestpolygon(privpath_t *pp)
}
pp->m = m;
- SAFE_MALLOC(pp->po, m, int);
+ SAFE_CALLOC(pp->po, m, int);
/* read off shortest path */
for (i=n, j=m-1; i>0; j--) {
@@ -620,7 +620,7 @@ static int bestpolygon(privpath_t *pp)
free(seg1);
return 0;
- malloc_error:
+ calloc_error:
free(pen);
free(prev);
free(clip0);
@@ -655,13 +655,13 @@ static int adjust_vertices(privpath_t *pp) {
dpoint_t s;
int r;
- SAFE_MALLOC(ctr, m, dpoint_t);
- SAFE_MALLOC(dir, m, dpoint_t);
- SAFE_MALLOC(q, m, quadform_t);
+ SAFE_CALLOC(ctr, m, dpoint_t);
+ SAFE_CALLOC(dir, m, dpoint_t);
+ SAFE_CALLOC(q, m, quadform_t);
r = privcurve_init(&pp->curve, m);
if (r) {
- goto malloc_error;
+ goto calloc_error;
}
/* calculate "optimal" point-slope representation for each line
@@ -827,7 +827,7 @@ static int adjust_vertices(privpath_t *pp) {
free(q);
return 0;
- malloc_error:
+ calloc_error:
free(ctr);
free(dir);
free(q);
@@ -875,7 +875,7 @@ static void smooth(privcurve_t *curve, double alphamax) {
}
curve->alpha0[j] = alpha; /* remember "original" value of alpha */
- if (alpha > alphamax) { /* pointed corner */
+ if (alpha >= alphamax) { /* pointed corner */
curve->tag[j] = POTRACE_CORNER;
curve->c[j][1] = curve->vertex[j];
curve->c[j][2] = p4;
@@ -1075,12 +1075,12 @@ static int opticurve(privpath_t *pp, double opttolerance) {
int *convc = NULL; /* conv[m]: pre-computed convexities */
double *areac = NULL; /* cumarea[m+1]: cache for fast area computation */
- SAFE_MALLOC(pt, m+1, int);
- SAFE_MALLOC(pen, m+1, double);
- SAFE_MALLOC(len, m+1, int);
- SAFE_MALLOC(opt, m+1, opti_t);
- SAFE_MALLOC(convc, m, int);
- SAFE_MALLOC(areac, m+1, double);
+ SAFE_CALLOC(pt, m+1, int);
+ SAFE_CALLOC(pen, m+1, double);
+ SAFE_CALLOC(len, m+1, int);
+ SAFE_CALLOC(opt, m+1, opti_t);
+ SAFE_CALLOC(convc, m, int);
+ SAFE_CALLOC(areac, m+1, double);
/* pre-calculate convexity: +1 = right turn, -1 = left turn, 0 = corner */
for (i=0; i<m; i++) {
@@ -1134,10 +1134,10 @@ static int opticurve(privpath_t *pp, double opttolerance) {
om = len[m];
r = privcurve_init(&pp->ocurve, om);
if (r) {
- goto malloc_error;
+ goto calloc_error;
}
- SAFE_MALLOC(s, om, double);
- SAFE_MALLOC(t, om, double);
+ SAFE_CALLOC(s, om, double);
+ SAFE_CALLOC(t, om, double);
j = m;
for (i=om-1; i>=0; i--) {
@@ -1182,7 +1182,7 @@ static int opticurve(privpath_t *pp, double opttolerance) {
free(areac);
return 0;
- malloc_error:
+ calloc_error:
free(pt);
free(pen);
free(len);
diff --git a/src/trace/potrace/trace.h b/src/trace/potrace/trace.h
index dc2b9247a..c53cdd10f 100644
--- a/src/trace/potrace/trace.h
+++ b/src/trace/potrace/trace.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2011 Peter Selinger.
+/* Copyright (C) 2001-2015 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 674254686..991d11feb 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -1,11 +1,10 @@
-
set(ui_SRC
clipboard.cpp
control-manager.cpp
dialog-events.cpp
draw-anchor.cpp
- interface.cpp
- object-edit.cpp
+ interface.cpp
+ object-edit.cpp
previewholder.cpp
shape-editor.cpp
tool-factory.cpp
@@ -56,8 +55,8 @@ set(ui_SRC
dialog/aboutbox.cpp
dialog/align-and-distribute.cpp
dialog/calligraphic-profile-rename.cpp
- dialog/color-item.cpp
dialog/clonetiler.cpp
+ dialog/color-item.cpp
dialog/debug.cpp
dialog/desktop-tracker.cpp
dialog/dialog-manager.cpp
@@ -86,31 +85,36 @@ set(ui_SRC
dialog/livepatheffect-add.cpp
dialog/livepatheffect-editor.cpp
dialog/lpe-fillet-chamfer-properties.cpp
+ dialog/lpe-powerstroke-properties.cpp
dialog/memory.cpp
dialog/messages.cpp
dialog/new-from-template.cpp
dialog/object-attributes.cpp
dialog/object-properties.cpp
+ dialog/objects.cpp
dialog/ocaldialogs.cpp
+ dialog/pixelartdialog.cpp
dialog/polar-arrange-tab.cpp
dialog/print-colors-preview-dialog.cpp
dialog/print.cpp
- dialog/symbols.cpp
- dialog/xml-tree.cpp
dialog/spellcheck.cpp
dialog/svg-fonts-dialog.cpp
dialog/swatches.cpp
+ dialog/symbols.cpp
+ dialog/tags.cpp
dialog/template-load-tab.cpp
dialog/template-widget.cpp
dialog/text-edit.cpp
dialog/tile.cpp
dialog/tracedialog.cpp
- dialog/pixelartdialog.cpp
dialog/transformation.cpp
dialog/undo-history.cpp
+ dialog/xml-tree.cpp
+ widget/addtoicon.cpp
widget/anchor-selector.cpp
widget/button.cpp
+ widget/clipmaskicon.cpp
widget/color-picker.cpp
widget/color-preview.cpp
widget/dock-item.cpp
@@ -121,10 +125,13 @@ set(ui_SRC
widget/frame.cpp
widget/gimpcolorwheel.c
widget/gimpspinscale.c
+ widget/highlight-picker.cpp
widget/imageicon.cpp
widget/imagetoggler.cpp
+ widget/insertordericon.cpp
widget/labelled.cpp
widget/layer-selector.cpp
+ widget/layertypeicon.cpp
widget/licensor.cpp
widget/notebook-page.cpp
widget/object-composite-settings.cpp
@@ -179,8 +186,8 @@ set(ui_SRC
dialog/arrange-tab.h
dialog/behavior.h
dialog/calligraphic-profile-rename.h
- dialog/color-item.h
dialog/clonetiler.h
+ dialog/color-item.h
dialog/debug.h
dialog/desktop-tracker.h
dialog/dialog-manager.h
@@ -200,8 +207,8 @@ set(ui_SRC
dialog/floating-behavior.h
dialog/font-substitution.h
dialog/glyphs.h
- dialog/guides.h
dialog/grid-arrange-tab.h
+ dialog/guides.h
dialog/icon-preview.h
dialog/inkscape-preferences.h
dialog/input.h
@@ -215,13 +222,13 @@ set(ui_SRC
dialog/new-from-template.h
dialog/object-attributes.h
dialog/object-properties.h
+ dialog/objects.h
dialog/ocaldialogs.h
dialog/panel-dialog.h
- dialog/polar-arrange-tab.h
dialog/pixelartdialog.h
+ dialog/polar-arrange-tab.h
dialog/print-colors-preview-dialog.h
dialog/print.h
-
dialog/spellcheck.h
dialog/svg-fonts-dialog.h
dialog/swatches.h
diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp
index 3da0e0043..077c6f5ca 100644
--- a/src/ui/dialog/filter-effects-dialog.cpp
+++ b/src/ui/dialog/filter-effects-dialog.cpp
@@ -211,7 +211,7 @@ private:
ComboBoxEnum<T>* combo;
};
-// Contains an arbitrary number of spin buttons that use seperate attributes
+// Contains an arbitrary number of spin buttons that use separate attributes
class MultiSpinButton : public Gtk::HBox
{
public:
diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp
index 49c949107..a90dfb155 100644
--- a/src/ui/tool/curve-drag-point.cpp
+++ b/src/ui/tool/curve-drag-point.cpp
@@ -54,7 +54,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/)
// delta is a vector equal 1/3 of distance from first to second
Geom::Point delta = (second->position() - first->position()) / 3.0;
// only update the nodes if the mode is bspline
- if(!_pm.isBSpline(false)){
+ if(!_pm.isBSpline()){
first->front()->move(first->front()->position() + delta);
second->back()->move(second->back()->position() - delta);
}
@@ -91,7 +91,7 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event)
Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta;
//modified so that, if the trace is bspline, it only acts if the SHIFT key is pressed
- if(!_pm.isBSpline(false)){
+ if(!_pm.isBSpline()){
first->front()->move(first->front()->position() + offset0);
second->back()->move(second->back()->position() + offset1);
}else if(weight>=0.8){
diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h
index cdbf34e9d..1bbcdd7ec 100644
--- a/src/ui/tool/multi-path-manipulator.h
+++ b/src/ui/tool/multi-path-manipulator.h
@@ -39,7 +39,7 @@ public:
virtual bool event(Inkscape::UI::Tools::ToolBase *, GdkEvent *event);
bool empty() { return _mmap.empty(); }
- unsigned size() { return _mmap.empty(); }
+ unsigned size() { return _mmap.size(); }
void setItems(std::set<ShapeRecord> const &);
void clear() { _mmap.clear(); }
void cleanup();
diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp
index eeea47e4d..08cc6708d 100644
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
@@ -192,7 +192,7 @@ void Handle::move(Geom::Point const &new_pos)
setRelativePos(new_delta);
//move the handler and its oposite the same proportion
- if(_pm().isBSpline()){
+ if(_pm().isBSpline()){
setPosition(_pm().BSplineHandleReposition(this,this));
this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),this));
}
@@ -222,7 +222,6 @@ void Handle::move(Geom::Point const &new_pos)
setPosition(_pm().BSplineHandleReposition(this,this));
this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),this));
}
-
}
void Handle::setPosition(Geom::Point const &p)
@@ -382,7 +381,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event)
std::vector<Inkscape::SnapCandidatePoint> unselected;
//if the snap adjustment is activated and it is not bspline
- if (snap && !_pm().isBSpline(false)) {
+ if (snap && !_pm().isBSpline()) {
ControlPointSelection::Set &nodes = _parent->_selection.allPoints();
for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) {
Node *n = static_cast<Node*>(*i);
@@ -486,7 +485,7 @@ Glib::ustring Handle::_getTip(unsigned state) const
char const *more;
// a trick to mark as bspline if the node has no strength, we are going to use it later
// to show the appropiate messages. We cannot do it in any different way becasue the function is constant
-
+ Handle *h = const_cast<Handle *>(this);
bool isBSpline = _pm().isBSpline();
bool can_shift_rotate = _parent->type() == NODE_CUSP && !other()->isDegenerate();
if (can_shift_rotate && !isBSpline) {
@@ -550,7 +549,7 @@ Glib::ustring Handle::_getTip(unsigned state) const
"<b>Auto node handle</b>: drag to convert to smooth node (%s)"), more);
}else{
return format_tip(C_("Path handle tip",
- "<b>BSpline node handle</b>: Shift to drag, double click to reset (%s)"), more);
+ "<b>BSpline node handle</b>: Shift to drag, double click to reset (%s). %g power"),more,_pm().BSplineHandlePosition(h,NULL));
}
}
}
@@ -1435,6 +1434,8 @@ Node *Node::nodeAwayFrom(Handle *h)
Glib::ustring Node::_getTip(unsigned state) const
{
bool isBSpline = _pm().isBSpline();
+ Handle *h = const_cast<Handle *>(&_front);
+ Handle *h2 = const_cast<Handle *>(&_back);
if (state_held_shift(state)) {
bool can_drag_out = (_next() && _front.isDegenerate()) || (_prev() && _back.isDegenerate());
if (can_drag_out) {
@@ -1469,7 +1470,7 @@ Glib::ustring Node::_getTip(unsigned state) const
"<b>%s</b>: drag to shape the path (more: Shift, Ctrl, Alt)"), nodetype);
}else if(_selection.size() == 1){
return format_tip(C_("Path node tip",
- "<b>BSpline node</b>: %g weight, drag to shape the path (more: Shift, Ctrl, Alt)"),noPower/*this->bsplineWeight*/);
+ "<b>BSpline node</b>: drag to shape the path (more: Shift, Ctrl, Alt). %g power"),_pm().BSplineHandlePosition(h,h2));
}
return format_tip(C_("Path node tip",
"<b>%s</b>: drag to shape the path, click to toggle scale/rotation handles (more: Shift, Ctrl, Alt)"), nodetype);
@@ -1479,7 +1480,7 @@ Glib::ustring Node::_getTip(unsigned state) const
"<b>%s</b>: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt)"), nodetype);
}else{
return format_tip(C_("Path node tip",
- "<b>BSpline node</b>: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt)"));
+ "<b>BSpline node</b>: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt). %g power"),_pm().BSplineHandlePosition(h,h2));
}
}
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp
index c8b986824..dbae69f2c 100644
--- a/src/ui/tool/path-manipulator.cpp
+++ b/src/ui/tool/path-manipulator.cpp
@@ -11,6 +11,7 @@
*/
#include "live_effects/lpe-powerstroke.h"
+#include "live_effects/lpe-bspline.h"
#include "live_effects/lpe-fillet-chamfer.h"
#include <string>
#include <sstream>
@@ -43,7 +44,6 @@
#include "ui/tool/multi-path-manipulator.h"
#include "xml/node.h"
#include "xml/node-observer.h"
-#include "live_effects/lpe-bspline.h"
namespace Inkscape {
namespace UI {
@@ -124,6 +124,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path,
, _show_path_direction(false)
, _live_outline(true)
, _live_objects(true)
+ , _is_bspline(false)
, _lpe_key(lpe_key)
{
if (_lpe_key.empty()) {
@@ -151,7 +152,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path,
_createControlPointsFromGeometry();
//Define if the path is BSpline on construction
- isBSpline(true);
+ recalculateIsBSpline();
}
PathManipulator::~PathManipulator()
@@ -1221,10 +1222,13 @@ int PathManipulator::BSplineGetSteps() const {
LivePathEffect::LPEBSpline const *lpe_bsp = NULL;
- if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){
- Inkscape::LivePathEffect::Effect const *thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE);
- if(thisEffect){
- lpe_bsp = dynamic_cast<LivePathEffect::LPEBSpline const*>(thisEffect->getLPEObj()->get_lpe());
+ SPLPEItem * path = dynamic_cast<SPLPEItem *>(_path);
+ if (path){
+ if(path->hasPathEffect()){
+ Inkscape::LivePathEffect::Effect const *thisEffect = path->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE);
+ if(thisEffect){
+ lpe_bsp = dynamic_cast<LivePathEffect::LPEBSpline const*>(thisEffect->getLPEObj()->get_lpe());
+ }
}
}
int steps = 0;
@@ -1235,19 +1239,24 @@ int PathManipulator::BSplineGetSteps() const {
}
// determines if the trace has bspline effect
-bool PathManipulator::isBSpline(bool recalculate){
- if(recalculate){
- _is_bspline = this->BSplineGetSteps() > 0;
+void PathManipulator::recalculateIsBSpline(){
+ if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()) {
+ Inkscape::LivePathEffect::Effect const *thisEffect = _path->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE);
+ if(thisEffect){
+ _is_bspline = true;
+ return;
+ }
}
- return _is_bspline;
+ _is_bspline = false;
}
bool PathManipulator::isBSpline() const {
- return BSplineGetSteps() > 0;
+ return _is_bspline;
}
// returns the corresponding strength to the position of the handlers
-double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){
+double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2)
+{
using Geom::X;
using Geom::Y;
if(h2){
@@ -1272,7 +1281,8 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){
}
// give the location for the handler in the corresponding position
-Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, Handle *h2){
+Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, Handle *h2)
+{
double pos = this->BSplineHandlePosition(h, h2);
return BSplineHandleReposition(h,pos);
}
@@ -1309,7 +1319,7 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE)
{
Geom::PathBuilder builder;
//Refresh if is bspline some times -think on path change selection, this value get lost
- isBSpline(true);
+ recalculateIsBSpline();
for (std::list<SubpathPtr>::iterator spi = _subpaths.begin(); spi != _subpaths.end(); ) {
SubpathPtr subpath = *spi;
if (subpath->empty()) {
@@ -1338,15 +1348,15 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE)
_spcurve->set_pathvector(pathv);
if (alert_LPE) {
/// \todo note that _path can be an Inkscape::LivePathEffect::Effect* too, kind of confusing, rework member naming?
- if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){
- Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::POWERSTROKE);
+ if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()) {
+ Inkscape::LivePathEffect::Effect* thisEffect = _path->getPathEffectOfType(Inkscape::LivePathEffect::POWERSTROKE);
if(thisEffect){
LivePathEffect::LPEPowerStroke *lpe_pwr = dynamic_cast<LivePathEffect::LPEPowerStroke*>(thisEffect->getLPEObj()->get_lpe());
if (lpe_pwr) {
lpe_pwr->adjustForNewPath(pathv);
}
}
- thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::FILLET_CHAMFER);
+ thisEffect = _path->getPathEffectOfType(Inkscape::LivePathEffect::FILLET_CHAMFER);
if(thisEffect){
LivePathEffect::LPEFilletChamfer *lpe_fll = dynamic_cast<LivePathEffect::LPEFilletChamfer*>(thisEffect->getLPEObj()->get_lpe());
if (lpe_fll) {
diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h
index 4d2bf4300..6dc1c9d09 100644
--- a/src/ui/tool/path-manipulator.h
+++ b/src/ui/tool/path-manipulator.h
@@ -107,7 +107,7 @@ private:
void _createControlPointsFromGeometry();
- bool isBSpline(bool recalculate = false);
+ void recalculateIsBSpline();
bool isBSpline() const;
double BSplineHandlePosition(Handle *h, Handle *h2 = NULL);
Geom::Point BSplineHandleReposition(Handle *h, Handle *h2 = NULL);
diff --git a/src/ui/tools/box3d-tool.h b/src/ui/tools/box3d-tool.h
index 1dd6bb5f8..33ae6d8e7 100644
--- a/src/ui/tools/box3d-tool.h
+++ b/src/ui/tools/box3d-tool.h
@@ -80,7 +80,7 @@ private:
Proj::Pt3 drag_ptC_proj;
bool ctrl_dragged; /* whether we are ctrl-dragging */
- bool extruded; /* whether shift-dragging already occured (i.e. the box is already extruded) */
+ bool extruded; /* whether shift-dragging already occurred (i.e. the box is already extruded) */
sigc::connection sel_changed_connection;
diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp
index d76b0d142..c3ef19507 100644
--- a/src/ui/tools/connector-tool.cpp
+++ b/src/ui/tools/connector-tool.cpp
@@ -49,7 +49,7 @@
* Much of the way connectors work for user-defined points has been
* changed so that it no longer defines special attributes to record
* the points. Instead it uses single node paths to define points
- * who are then seperate objects that can be fixed on the canvas,
+ * who are then separate objects that can be fixed on the canvas,
* grouped into objects and take full advantage of all transform, snap
* and align functionality of all other objects.
*
diff --git a/src/ui/tools/dynamic-base.h b/src/ui/tools/dynamic-base.h
index c948fa286..095af8f88 100644
--- a/src/ui/tools/dynamic-base.h
+++ b/src/ui/tools/dynamic-base.h
@@ -47,7 +47,7 @@ protected:
/** accumulated shape which ultimately goes in svg:path */
SPCurve *accumulated;
- /** canvas items for "comitted" segments */
+ /** canvas items for "committed" segments */
GSList *segments;
/** canvas item for red "leading" segment */
diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp
index 5be84eb76..b27859ebb 100644
--- a/src/ui/tools/gradient-tool.cpp
+++ b/src/ui/tools/gradient-tool.cpp
@@ -321,7 +321,7 @@ sp_gradient_context_add_stops_between_selected_stops (GradientTool *rc)
if (d->point_type == POINT_RG_FOCUS) {
/*
* There are 2 draggables at the center (start) of a radial gradient
- * To avoid creating 2 seperate stops, ignore this draggable point type
+ * To avoid creating 2 separate stops, ignore this draggable point type
*/
continue;
}
diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp
index f8045a029..a4b903960 100644
--- a/src/ui/tools/node-tool.cpp
+++ b/src/ui/tools/node-tool.cpp
@@ -75,7 +75,7 @@
* - ControlPointSelection: keeps track of node selection and a set of nodes that can potentially
* be selected. There can be more than one selection. Performs actions that require no
* knowledge about the path, only about the nodes, like dragging and transforms. It is not
- * specific to nodes and can accomodate any control point derived from SelectableControlPoint.
+ * specific to nodes and can accommodate any control point derived from SelectableControlPoint.
* Transforms nodes in response to transform handle events.
* - TransformHandleSet: displays nodeset transform handles and emits transform events. The aim
* is to eventually use a common class for object and control point transforms.
diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp
index d28b7c27a..d5f501163 100644
--- a/src/ui/tools/pen-tool.cpp
+++ b/src/ui/tools/pen-tool.cpp
@@ -2143,7 +2143,7 @@ bool PenTool::_undoLastPoint() {
this->p[1] = this->p[0];
}
- // asign the value in a third of the distance of the last segment.
+ // assign the value in a third of the distance of the last segment.
if (this->bspline){
this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]);
}
@@ -2165,7 +2165,7 @@ bool PenTool::_undoLastPoint() {
this->green_curve->backspace();
}
- // assign the value of this->p[1] to the oposite of the green line last segment
+ // assign the value of this->p[1] to the opposite of the green line last segment
if (this->spiro){
Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(this->green_curve->last_segment());
if ( cubic ) {
diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp
index ec7d10e13..0399b1e55 100644
--- a/src/ui/tools/spray-tool.cpp
+++ b/src/ui/tools/spray-tool.cpp
@@ -406,7 +406,7 @@ static bool sp_spray_recursive(SPDesktop *desktop,
parent->appendChild(copy);
SPObject *new_obj = doc->getObjectByRepr(copy);
- item_copied = dynamic_cast<SPItem *>(new_obj); // Convertion object->item
+ item_copied = dynamic_cast<SPItem *>(new_obj); // Conversion 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));
diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp
index 8e647ebb4..0a5697661 100644
--- a/src/ui/widget/page-sizer.cpp
+++ b/src/ui/widget/page-sizer.cpp
@@ -242,7 +242,13 @@ PageSizer::PageSizer(Registry & _wr)
_marginBottom( _("Botto_m:"), _("Bottom margin"), "fit-margin-bottom", _wr),
_lockMarginUpdate(false),
_scaleX(_("Scale _x:"), _("Scale X"), "scale-x", _wr),
+ _scaleY(_("Scale _y:"), _("Scale Y"), "scale-y", _wr),
_lockScaleUpdate(false),
+ _viewboxX(_("X:"), _("X"), "viewbox-x", _wr),
+ _viewboxY(_("Y:"), _("Y"), "viewbox-y", _wr),
+ _viewboxW(_("Width:"), _("Width"), "viewbox-width", _wr),
+ _viewboxH(_("Height:"), _("Height"), "viewbox-height", _wr),
+ _lockViewboxUpdate(false),
_widgetRegistry(&_wr)
{
// set precision of scalar entry boxes
@@ -254,7 +260,21 @@ PageSizer::PageSizer(Registry & _wr)
_marginRight.setDigits(5);
_marginBottom.setDigits(5);
_scaleX.setDigits(5);
+ _scaleY.setDigits(5);
+ _viewboxX.setDigits(2);
+ _viewboxY.setDigits(2);
+ _viewboxW.setDigits(2);
+ _viewboxH.setDigits(2);
+
_scaleX.setRange( 0.00001, 100000 );
+ _scaleY.setRange( 0.00001, 100000 );
+ _viewboxX.setRange( -100000, 100000 );
+ _viewboxY.setRange( -100000, 100000 );
+ _viewboxW.setRange( 0, 200000 );
+ _viewboxH.setRange( 0, 200000 );
+
+ _scaleY.set_sensitive (false); // We only want to display Y scale.
+
_wr.setUpdating (false);
//# Set up the Paper Size combo box
@@ -435,21 +455,62 @@ PageSizer::PageSizer(Registry & _wr)
_scaleTable.set_row_spacing(4);
_scaleTable.set_column_spacing(4);
- _dimensionWidth.set_hexpand();
- _dimensionWidth.set_vexpand();
_scaleTable.attach(_scaleX, 0, 0, 1, 1);
+ _scaleTable.attach(_scaleY, 1, 0, 1, 1);
- _dimensionUnits.set_hexpand();
- _dimensionUnits.set_vexpand();
- _scaleTable.attach(_scaleLabel, 1, 0, 1, 1);
+ _scaleTable.attach(_scaleLabel, 2, 0, 1, 1);
+ _scaleTable.attach(_scaleWarning, 0, 1, 2, 1);
+ _viewboxExpander.set_hexpand();
+ _viewboxExpander.set_vexpand();
+ _scaleTable.attach(_viewboxExpander, 0, 2, 2, 1);
#else
- _scaleTable.resize(2, 1);
+ _scaleTable.resize(3, 2);
_scaleTable.set_row_spacings(4);
_scaleTable.set_col_spacings(4);
_scaleTable.attach(_scaleX, 0,1, 0,1);
- _scaleTable.attach(_scaleLabel, 1,2, 0,1);
+ _scaleTable.attach(_scaleY, 1,2, 0,1);
+ _scaleTable.attach(_scaleLabel, 2,3, 0,1);
+ _scaleTable.attach(_scaleWarning, 0,3, 1,2, Gtk::FILL);
+ _scaleTable.attach(_viewboxExpander, 0,3, 2,3);
#endif
+ _scaleWarning.set_label(_("While SVG allows non-uniform scaling it is recommended to use only uniform scaling in Inkscape. To set a non-uniform scaling, set the 'viewBox' directly."));
+ _scaleWarning.set_line_wrap( true );
+
+ _viewboxExpander.set_use_underline();
+ _viewboxExpander.set_label(_("_Viewbox..."));
+ _viewboxExpander.add(_viewboxTable);
+
+#if WITH_GTKMM_3_0
+ _viewboxTable.set_row_spacing(2);
+ _viewboxTable.set_column_spacing(2);
+
+ _viewboxX.set_hexpand();
+ _viewboxX.set_vexpand();
+ _viewboxTable.attach(_viewboxX, 0, 0, 1, 1);
+
+ _viewboxY.set_hexpand();
+ _viewboxY.set_vexpand();
+ _viewboxTable.attach(_viewboxY, 1, 0, 1, 1);
+
+ _viewboxW.set_hexpand();
+ _viewboxW.set_vexpand();
+ _viewboxTable.attach(_viewboxW, 0, 1, 1, 1);
+
+ _viewboxH.set_hexpand();
+ _viewboxH.set_vexpand();
+ _viewboxTable.attach(_viewboxH, 1, 1, 1, 1);
+
+#else
+ _viewboxTable.set_border_width(4);
+ _viewboxTable.set_row_spacings(2);
+ _viewboxTable.set_col_spacings(2);
+ _viewboxTable.attach(_viewboxX, 0,1, 0,1);
+ _viewboxTable.attach(_viewboxY, 1,2, 0,1);
+ _viewboxTable.attach(_viewboxW, 0,1, 1,2);
+ _viewboxTable.attach(_viewboxH, 1,2, 1,2);
+#endif
+
_wr.setUpdating (true);
updateScaleUI();
_wr.setUpdating (false);
@@ -478,7 +539,11 @@ PageSizer::init ()
_changedh_connection = _dimensionHeight.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
_changedu_connection = _dimensionUnits.getUnitMenu()->signal_changed().connect (sigc::mem_fun (*this, &PageSizer::on_units_changed));
_fitPageButton.signal_clicked().connect(sigc::mem_fun(*this, &PageSizer::fire_fit_canvas_to_selection_or_drawing));
- _changeds_connection = _scaleX.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_scale_changed));
+ _changeds_connection = _scaleX.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_scale_changed));
+ _changedvx_connection = _viewboxX.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_viewbox_changed));
+ _changedvy_connection = _viewboxY.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_viewbox_changed));
+ _changedvw_connection = _viewboxW.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_viewbox_changed));
+ _changedvh_connection = _viewboxH.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_viewbox_changed));
show_all_children();
}
@@ -744,10 +809,6 @@ void
PageSizer::updateScaleUI()
{
- if (_lockScaleUpdate) {
- return;
- }
-
static bool _called = false;
if (_called) {
return;
@@ -756,28 +817,56 @@ PageSizer::updateScaleUI()
_called = true;
_changeds_connection.block();
+ _changedvx_connection.block();
+ _changedvy_connection.block();
+ _changedvw_connection.block();
+ _changedvh_connection.block();
SPDesktop *dt = SP_ACTIVE_DESKTOP;
if (dt) {
SPDocument *doc = dt->getDocument();
+
+ // Update scale
Geom::Scale scale = doc->getDocumentScale();
-
SPNamedView *nv = dt->getNamedView();
std::stringstream ss;
ss << _("User units per ") << nv->display_units->abbr << "." ;
_scaleLabel.set_text( ss.str() );
- double scaleX_inv =
- Inkscape::Util::Quantity::convert( scale[Geom::X], "px", nv->display_units );
- if( scaleX_inv > 0 ) {
- _scaleX.setValue(1.0/scaleX_inv);
- } else {
- // Should never happen
- std::cerr << "PageSizer::updateScaleUI(): Invalid scale value: " << scaleX_inv << std::endl;
- _scaleX.setValue(1.0);
+ if( !_lockScaleUpdate ) {
+
+ double scaleX_inv =
+ Inkscape::Util::Quantity::convert( scale[Geom::X], "px", nv->display_units );
+ if( scaleX_inv > 0 ) {
+ _scaleX.setValue(1.0/scaleX_inv);
+ } else {
+ // Should never happen
+ std::cerr << "PageSizer::updateScaleUI(): Invalid scale value: " << scaleX_inv << std::endl;
+ _scaleX.setValue(1.0);
+ }
+ }
+
+ { // Don't need to lock as scaleY widget not linked to callback.
+ double scaleY_inv =
+ Inkscape::Util::Quantity::convert( scale[Geom::Y], "px", nv->display_units );
+ if( scaleY_inv > 0 ) {
+ _scaleY.setValue(1.0/scaleY_inv);
+ } else {
+ // Should never happen
+ std::cerr << "PageSizer::updateScaleUI(): Invalid scale value: " << scaleY_inv << std::endl;
+ _scaleY.setValue(1.0);
+ }
}
+ if( !_lockViewboxUpdate ) {
+ Geom::Rect viewBox = doc->getViewBox();
+ _viewboxX.setValue( viewBox.min()[Geom::X] );
+ _viewboxY.setValue( viewBox.min()[Geom::Y] );
+ _viewboxW.setValue( viewBox.width() );
+ _viewboxH.setValue( viewBox.height() );
+ }
+
} else {
// Should never happen
std::cerr << "PageSizer::updateScaleUI(): No active desktop." << std::endl;
@@ -785,6 +874,10 @@ PageSizer::updateScaleUI()
}
_changeds_connection.unblock();
+ _changedvx_connection.unblock();
+ _changedvy_connection.unblock();
+ _changedvw_connection.unblock();
+ _changedvh_connection.unblock();
_called = false;
}
@@ -801,6 +894,7 @@ PageSizer::on_value_changed()
setDim (Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionUnits.getUnit()),
Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit()));
}
+
void
PageSizer::on_units_changed()
{
@@ -830,13 +924,44 @@ PageSizer::on_scale_changed()
double scaleX_inv = Inkscape::Util::Quantity(1.0/value, nv->display_units ).value("px");
_lockScaleUpdate = true;
- doc->setDocumentScale( 1.0/scaleX_inv );
+ doc->setDocumentScale( 1.0/scaleX_inv );
+ updateScaleUI();
_lockScaleUpdate = false;
DocumentUndo::done(doc, SP_VERB_NONE, _("Set page scale"));
}
}
}
+/**
+ * Callback for viewbox widgets
+ */
+void
+PageSizer::on_viewbox_changed()
+{
+ if (_widgetRegistry->isUpdating()) return;
+
+ double viewboxX = _viewboxX.getValue();
+ double viewboxY = _viewboxY.getValue();
+ double viewboxW = _viewboxW.getValue();
+ double viewboxH = _viewboxH.getValue();
+
+ if( viewboxW > 0 && viewboxH > 0) {
+ SPDesktop *dt = SP_ACTIVE_DESKTOP;
+ if (dt) {
+ SPDocument *doc = dt->getDocument();
+ _lockViewboxUpdate = true;
+ doc->setViewBox( Geom::Rect::from_xywh( viewboxX, viewboxY, viewboxW, viewboxH ) );
+ updateScaleUI();
+ _lockViewboxUpdate = false;
+ DocumentUndo::done(doc, SP_VERB_NONE, _("Set 'viewBox'"));
+ }
+ } else {
+ std::cerr
+ << "PageSizer::on_viewbox_changed(): width and height must both be greater than zero."
+ << std::endl;
+ }
+}
+
} // namespace Widget
} // namespace UI
} // namespace Inkscape
diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h
index f9a72d9f3..0eea28e61 100644
--- a/src/ui/widget/page-sizer.h
+++ b/src/ui/widget/page-sizer.h
@@ -264,17 +264,38 @@ protected:
#endif
Gtk::Label _scaleLabel;
+ Gtk::Label _scaleWarning;
RegisteredScalar _scaleX;
+ RegisteredScalar _scaleY;
bool _lockScaleUpdate;
+ // Viewbox
+ Gtk::Expander _viewboxExpander;
+#if WITH_GTKMM_3_0
+ Gtk::Grid _viewboxTable;
+#else
+ Gtk::Table _viewboxTable;
+#endif
+
+ RegisteredScalar _viewboxX;
+ RegisteredScalar _viewboxY;
+ RegisteredScalar _viewboxW;
+ RegisteredScalar _viewboxH;
+ bool _lockViewboxUpdate;
+
//callback
void on_value_changed();
void on_units_changed();
void on_scale_changed();
+ void on_viewbox_changed();
sigc::connection _changedw_connection;
sigc::connection _changedh_connection;
sigc::connection _changedu_connection;
sigc::connection _changeds_connection;
+ sigc::connection _changedvx_connection;
+ sigc::connection _changedvy_connection;
+ sigc::connection _changedvw_connection;
+ sigc::connection _changedvh_connection;
Registry *_widgetRegistry;
diff --git a/src/uri-references.cpp b/src/uri-references.cpp
index b23bed74a..2518c173e 100644
--- a/src/uri-references.cpp
+++ b/src/uri-references.cpp
@@ -65,7 +65,7 @@ void URIReference::attach(const URI &uri) throw(BadURIException)
skip = true;
}
- // The path contains references to seperate document files to load.
+ // The path contains references to separate document files to load.
if(document && uri.getPath() && !skip ) {
std::string base = document->getBase() ? document->getBase() : "";
std::string path = uri.getFullPath(base);